- Home /
Setting Local Velocity Of A RigidBody
I'm currently using this to de-accelerate my player:
if (grounded)
{
if (!Input.GetButton("Horizontal"))
rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVelx, walkDeacceleration);
if (!Input.GetButton("Vertical"))
rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVelz, walkDeacceleration);
}
The problem is velocity.x and y aren't local velocities. What should I be using instead to modify the rigidbody's local velocity?
Thanks very much!
Do not do this. This is completely wrong. Add forces.
As a general rule, never set the velocity of anything. (There are exceptions, but this is not one.)
See my answer at the bottom - I wouldn't take the force statement quite so seriously. Totally overriding velocities can be bad practice (as it means you're ignoring everything else that's going on!), but scaling them up/down or adding/subtracting to them isn't really a problem. In fact that's basically what AddForce does!
Answer by Vox Nephila · Jul 06, 2013 at 08:39 PM
Personally, I would use rigidbody.AddRelativeForce() and just put negative numbers in there. That should achieve what you are asking.
1) Rigidbody.velocity is OF COURSE in global coordinates.
2) Note that OF COURSE you can just get the velocity in GLOBAL coords and indeed ....... ADD FORCE IN GLOBAL COORDS !! "AddForce" NOT "AddRelativeForce"
3) If FOR SO$$anonymous$$E STRANGE REASON you need to add "local" force --- RTF$$anonymous$$ --- Rigidbody.AddRelativeForce !!!
4) For goodness sake .. just add some drag
Answer by Fattie · Dec 15, 2015 at 03:56 PM
For goodness sake ...
to add force opposite the current velocity, of course you just do this:
rigidbody.AddForce( -rigidbody.velocity )
for example, probably something like
rigidbody.AddForce(-rigidbody.velocity*Time.deltaTime);
or just add drag
rigidbody.drag = 10f
note that of course drag goes along the direction of velocity. what else could it do?
If for some reason you want to add forces in the local coords, Unity give you AddForce
AND they give you AddRelativeForce
, the latter is in local position coords.
(NOTE - you may be confusing your local positional frame of reference, with, your local velocity frame of reference - recall there's no particular reason an object has to be pointing the way it is heading. But you should not even have to deal with any of that, it is irrelevant here.)
Note that if, for some incredible reason, you want to calculate "local" velocity. What you're trying to do is Transform a direction from world space to local space.
You need only use google for "Unity3d Transform a direction from world space to local space", the first result is the Unity command for "Transforms a direction from world space to local space".
But again, this won't help you and is not relevant.
Do you realise @Fattie that writing things like 'for goodness sake' and 'OF COURSE' is just unhelpful, and generally implies somebody has asked something stupid. At some point we all didn't know something, and have all asked questions that other people could consider silly if they wanted. I just mention it because perhaps you didn't realise that what you wrote sounds quite demeaning and not very nice.
Also, your answer is incorrect - the question specifically needs to takes into account the current velocity within the objects local frame of reference, as it is attempting to reduce both the sideways and forwards motion from the point of view of the player independently. So arguably, for goodness sake, your answer is wrong.
Answer by wibble82 · Dec 15, 2015 at 04:03 PM
Well, as some people here have said, you can either modify the velocity of a rigid body directly, or you can do it using AddForce/AddRelativeForce. Ultimately they are both exactly the same thing.
The AddForce functions are simply functions that allow you to add to the velocity of a rigid body with a bit of extra maths. For example, the basic 'AddForce' version adds a force (in newtons) which adds a number to the velocity that takes into account both the rigid body's mass and the time step. Ultimately though its still just adding a number!
Onto your question, I think what you're really asking is 'how do I break down the rigid body velocity into the bit that points in the same direction as the player, and the bit that points to the players side'. (and in theory the bit that points up too?
We can break down the rigid body's velocity into 3 values, mess with them, and then add them back up in this fairly long winded bit of code:
//get the velocity
Vector3 myVelocity = rigidBody.velocity;
//get the 3 floats that represent how the rigid body is moving relative to our own transform
float velocityForwards = Vector3.Dot(myVelocity,transform.forwards);
float velocitySideways = Vector3.Dot(myVelocity,transform.right);
float velocityUp = Vector3.Dot(myVelocity,transform.up);
//we could now fiddle with them
velocityForwards *= 0.5f; //half our forwards velocity
velocitySideways = 0; //totally kill our sideways velocity!
//and add them back up to get a new velocity
rigidBody.velocity = velocityForwards * transform.forwards + velocitySideways * transform.right + velocityUp * transform.up;
But fortunately Unity provides some functions to make that a bit easier:
//get the velocity
Vector3 myVelocity = rigidBody.velocity;
//convert it to 'local space', so the x is 'how much along our right', etc
myVelocity = transform.InverseTransformDirection(myVelocity);
//we could now fiddle with the individual components
myVelocity.z *= 0.5f; //half our forwards velocity
myVelocity.x = 0; //totally kill our sideways velocity!
//and convert back into 'world space'
rigidBody.velocity = transform.TransformDirection(myVelocity);
Personally I don't think there's any massive gain to messing with force functions here, as you genuinely do just want to mess with the player's velocity. But if you did we could still do something like:
//get the velocity
Vector3 myVelocity = rigidBody.velocity;
//convert it to 'local space', so the x is 'how much along our right', etc
myVelocity = transform.InverseTransformDirection(myVelocity);
//we could now fiddle with the individual components
Vector3 amountToAccelerate = Vector3.zero;
amountToAccelerate.z = -myVelocity.z*0.1f; //we are going to reduce our current velocity by 10% along our forwards
//and apply it to the rigid body (we don't need to convert back to world space, as AddRelativeForce does that internally)
rigidBody.AddRelativeForce(amountToAccelerate,ForceMode.Acceleration);
-Chris
"Ultimately they are both exactly the same thing" This is wrong Chris. You are affecting how the PhysX engine (which controls rigidbodys) works. The reason that the unity manual says in huge letters
DO NOT $$anonymous$$ODIFY THE VELOCITY OF RIGIDBODY
is that it will "mess-up" the physics calculations that frame, and typically result in stuttering or other problems. Apart from anything else, you may need to do this in LateUpdate, etc etc
(Note that you CAN in some rare circumstances directly set the velocity of a rigidbody, but there is no connection to the beginner question here.)
To slow a body down in a game engine you just do this
rigidbody.AddForce( -rigidbody.velocity )
very commonplace
Dude, I've been working and writing physics engines for AAA games for the past 14 years, and have worked with the PhysX source code on multiple occasions.
I can assure you that when used correctly, modifying the velocity is not a problem - provided that IS what you want it to do.
The unity manual recommends against it because it 'can result in unrealistic behaviour'. This is entirely correct - realistic physics involves taking into account mass, and for continuous forces, the time step.
However the question is not referring to 'realism' - the desire is to simply reduce the velocity each frame. In that case, the correct approach is to do just that.
Your answer
![](https://koobas.hobune.stream/wayback/20220613105612im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Velocity relative to Local Axis 1 Answer
Set The Local Velocity Of A Rigidbody 2 Answers
How do you directly add to velocity in a relative manner? 1 Answer
How to use local angular velocity? 1 Answer
velocity direction 1 Answer