# Velocity of a transform?

I want to calculate the velocity of an object, that doesn’t have a rigidbody . The only way I can do that is to get the difference in the position of the object from the last frame and the current frame. However my code isn’t calculating it really well. It mesures different speed all the time. Here’s my code, can you tell me what’s wrong:

``````private var ballSpeed : Vector3;
private var lastPos : Vector3;
var ball : GameObject;

function Start() {
lastPos = transform.InverseTransformDirection(transform.position);
}

function Update () {
transform.rotation = ball.GetComponent("BallControl_local").guideObject.transform.rotation;
if(lastPos != transform.InverseTransformDirection(transform.position)){
ballSpeed = transform.InverseTransformDirection(transform.position) - lastPos;
lastPos = transform.InverseTransformDirection(transform.position);
}
print(ballSpeed * 100);
}
``````

Maybe it’s because the time between frames is always different… Try to include this element with Time.deltaTime:

1 Like

Yes, exactly! The framerate’s different, but this object is a child of a rigidbody and the movement of the rigidbodies is not affected by framerate, so I’m trying to calculate the speed of that rigidbody. Now you will say “use rigidbody.velocity”, but this is not the case. The rigidbody is the player and it’s a ball. It rolls around the level and if I try to InverseTransformDirection(rigidbody.velocity) I will get different values, because the ball changes it’s rotation all the time. Now here comes this “Speedometer” which code I posted above. It aligns with the camera, which orbits around the ball. The camera always poitns upwards with it’s green arrow and it will not rotate in any way unless I move my mouse. The speedometer object get’s the rotation of the X component of the camera, which only rotates horizontally.

When I first started to write the code of the speedometer, I used Time.deltaTime, but then I reallized that I’m dealing with something that’s framerate independant. Maybe I’m not right here, yes, the numbers would slightly differ, but I’ll be getting the real distance, that has been travelled from the last to the current frame.

I found a problem with my system. When I rotate the camera on the X, ballSpeed.x and ballSpeed.z could reach up to 2000 depending on how fast I rotate the camera. That doesn’t make sence to me, because I’m calculating the position, not the rotation. Maybe that’s the problem.

Hello there!

Your problem is that you think InverseTransformPosition is something completly different than what it actually is.
You’ll want to cache away the previous position each update and don’t forget to take Time.deltaTime into the calculation.

Alright, so Time.deltaTime it is, but what do you mean by “cache away”? I couldn’t follow. And what is InverseTransformPosition then? I read the manual for every single thing, but maybe I haven’t understood the concept of it.

Excuse my earlier rather vague answer, I was a bit stressed.

Now that I have a second look at your code you already “cache away”, that is save, the last position. I see no reason to use InverseTransformDirection in this case, it’s used to transform a world direction to a local direction. If you wish to calculate the velocity you don’t need to care about the direction, only the distance. Hence if it’s the velocity you want, it should be represented as a float, as opposed to a vector.

In this piece of code I fetch the velocity in vector form though. The actual velocity in it’s float form is ballSpeed.normalized.

``````private var ballSpeed : Vector3;
private var lastPos : Vector3;

function Start() {
lastPos = transform.position;
}

function Update () {
if(lastPos != transform.position) {
ballSpeed = transform.position - lastPos;
ballSpeed /= Time.deltaTime;
lastPos = transform.position;
}
print(ballSpeed.magnitude);
}
``````

And that should do the trick.

1 Like

Myx has the right solution. However, I have a tough time getting it to report accurately unless I put the velocity calculation stuff in FixedUpdate()… ohh wait nevermind I see he’s dividing it by Time.deltaTime, that would work too

An interesting trick to note: If you’re using the locomotion system and building a multiplayer game, you can easily convert it to work in a networked game by changing MovementTracker.cs to use a velocity calculation like this instead of using CharacterController.velocity, and it will work like a charm

No problem, thanks for the reply, hope you feel better now

Yes, exactly! I need to get the local velocity of the transform so I can get the velocity in the direction of the camera’s z and x axes. I want to use this so my ball can accelerate until certail speed is reached. I can use magnitude, but it’s pretty basic, I need to know the speed in each direction, relative to the camera’s direction.

I need to use the speedometer code in conjunction with those lines in the player ball code:

``````if(speedometer.GetComponent("Speedometer").ballSpeed.z <= 10  speedometer.GetComponent("Speedometer").ballSpeed.z >= -15)
rigidbody.velocity +=  yInput * torqueMultiplier /10;
if(speedometer.GetComponent("Speedometer").ballSpeed.x <= 10  speedometer.GetComponent("Speedometer").ballSpeed.x >= -15)
rigidbody.velocity +=  xInput * torqueMultiplier /10;
``````

I tried your method, but it calculates the velocity with the world axis. I tried to add an additional line bellow the code:

``````ballSpeed = transform.TransformDirection(ballSpeed);
``````

But that keeps giving me random numbers and the ball accelerates to infinity .

EDIT* Hi, legend411, thanks for the advice! However I’m scripting my own system. I hate using stuff, that’s already made by someone, it confuses me

Ahh, yeah. This will only tell you the object world x, y, and z velocity. If you want to know the actual object’s velocity, you want to check the dot product of the normalized world velocity and the objects forward vector, and the dot product of the normalized world velocity and the objects right vector. I do something like this to control my own animations (I don’t use the locomotion system either, because its a bit a performance hog ) Here is the bulk of my script, my my animation stuff removed and replaced with some prints:

``````private var velocity : Vector3;
private var prevPos : Vector3;

function FixedUpdate (){
velocity = (transform.position - prevPos)/Time.deltaTime;
prevPos = transform.position;
}

function Update(){

velocity.y = 0;
var velocityMagnitude = velocity.magnitude;
velocity = velocity.normalized;
var fwdDotProduct = Vector3.Dot(transform.forward, velocity);
var rightDotProduct = Vector3.Dot(transform.right, velocity);

if(fwdDotProduct > 0.85){
print("I am moving forward");
}
else if(fwdDotProduct < -0.85){
print("I am moving backward");
}
else if(fwdDotProduct > 0.4  rightDotProduct < 0){
print("I am moving diagonally forward and left");
}
else if(fwdDotProduct > 0.4  rightDotProduct > 0){
print("I am moving diagonally forward and right");
}
else if(fwdDotProduct < -0.4  rightDotProduct < 0){
print("I am moving diagonally backward and left");
}
else if(fwdDotProduct < -0.4  rightDotProduct > 0){
print("I am moving diagonally backward and right");
}
else if(rightDotProduct < 0){
print("I am moving left");
}
else if(rightDotProduct > 0){
print("I am moving right");
}
else{
print("I am not moving");
}

}
``````
1 Like

But I don’t get it. How can I get the speed of the transform if I use Dot. Dot can have values from -1 to 1. You get the direction of the movement, I need to get the speed in a certain direcition. This whole Dot thing has always been confusing me, I’ve been reading about it in internet, but still it’s not completely clear to me, so maybe I just don’t follow correctly

You can’t, but by using both the dot products and the velocity magnitude you can.If you look at my above snippet, I store the velocity.magnitude as a new var (velocityMagnitude) before I normalize the transform velocity I calculated for the dot products.

Then, by comparing the resulting products you can tell if the direction the object is moving is the same as the direction the object is facing (for instance, in the above example, when the fwdDotProduct is greater than 0.85, the object is facing the same direction he is moving, so he is therefore moving forward)… then you would just check the velocityMagnitude to know how fast he’s moving in that direction.

Oh, right! That’s a good idea. It seems reasonable, but isn’t there really any other way to do it? I could try it, but this only works in certain conditions. It’s OK, I think that will work in my case, but if there’s a way to get the REAL local velocity of the transform without the issues I’m having, it would be awesome.

I’m assuming you mean an x, y, z vector3 that corresponds to the local velocity of the object; its just a matter of combining what I just explained to you and packaging into a vector3, based on the dot products of the world velocity and the object’s transform.right, transform.up, and transform.right. Something like this:

``````private var velocity : Vector3;
private var prevPos : Vector3;

function FixedUpdate (){
velocity = (transform.position - prevPos)/Time.deltaTime;
prevPos = transform.position;
}

function Update(){

var fwdDotProduct = Vector3.Dot(transform.forward, velocity);
var upDotProduct = Vector3.Dot(transform.up, velocity);
var rightDotProduct = Vector3.Dot(transform.right, velocity);

var velocityVector : Vector3 = new Vector3(rightDotProduct, upDotProduct, fwdDotProduct);

print(velocityVector);

}
``````

I just tested that, and it works fine. should be exactly what you’re looking for.

1 Like

Sweet! That’s the solution I needed! Thank you very much! You just made my day!

How exactly do i turn this into checking the magnitude based velocity in the forward direction?