I have been trying to make a speedometer for a racing game I'm making, but all the methods of making a speedometer I know of don't work on the vehicle wrapper for some reason. It may be that there are either too little solutions to this problem posted to the internet or I'm terrible at coding in Python.

Here are some of the resources I've tried to use in several attempts.

Number one

Number 2

Number 3

Thanks to anyone who helps.

  • $\begingroup$ What is the issue: A) measuring the speed B) the display C) the communication between the A) and B) $\endgroup$ – Monster Jan 10 '17 at 6:32
  • $\begingroup$ Mostly A, I've tried a lot of ways to measure the speed to no avail. However I would love to have B explained as well, to know how to make a display like a real car speedometer. $\endgroup$ – JakoNintenCraft Jan 10 '17 at 16:14
  • $\begingroup$ I will focus on A). You can find a possible solution on B) and C) at blenderartists.org/forum/showthread.php?249078 $\endgroup$ – Monster Jan 11 '17 at 6:29

How to measure speed

Speed by build-in Physics

When you let the build-in Physics engine calculate the motion of your game object (dynamic, rigid body etc.) you can directly ask the game object.

The object will provide you the current linear velocity (there is an angular velocity too). The linear velocity is a vector that tells you the direction and the speed the object traveled since the last frame. The speed is the length of the vector (speed can never become negative!).

import bge 

object = bge.logic.getCurrentController().owner
velocity = object.getLinearVelocity()
speed = velocity.length

Speed by positional change

In some situations you can't or do not want to use the build-in physics engine. In that case you can "manually" calculate the speed from positional changes.

This method assumes the object traveled from the location of the last frame to the current location with constant speed on a direct line. Typically this is a pretty save assumption (but it does not consider if the object really moved or teleported such as static objects do).

Here we use the school math:

speed = distance (last position, current position) / time

We need to record the current position, to be used within the formula of he next frame, while we use the recorded position of the last frame. The time is the reciprocity of the frame rate (typically 60):

time = 1/frame rate

This means you can calculate the speed this way:

import bge 

object = bge.logic.getCurrentController().owner
lastPosition = object.get("lastPosition", object.worldPosition)
object["lastPosition"] = object.worldPosition.copy()

step = object.worldPosition - lastPosition
speed = step * bge.logic.getLogicTicRate()

What to do with the speed?

Just now the speed is in a local variable and will get lost as soon as you leave local space.

From here you can place it in a property:

object["speed"] = speed

to be used within other Logic Bricks (including other Python code).

or you send it in a message:

bge.logic.sendMessage("speed changed", str(speed))

You can do that even with a message actuator:

messageActuator.body = str(speed)

or any other logic brick.

How to get the speed for displaying?

Dependent what you did with the value, you can retrieve it an use it e.g. in a Text Object:

for body in messageSensor.bodies:
    textObject.text = body

or as property to play an action: for body in messageSensor.bodies: actionPlayer["frame"] = float(body)

.... There are really many options.

The message method is described in detail in the BGE Guide to Messages

| improve this answer | |
  • $\begingroup$ I just noticed that there is a small mistake within the code you gave. In the one that says ' speed = velocity.length()' There should be no parentheses on this. $\endgroup$ – JakoNintenCraft Jan 14 '17 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.