Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ProjectCryken · Jul 06, 2013 at 08:25 PM · rigidbodyvelocitylocal

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!

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Jul 06, 2013 at 10:40 PM 0
Share

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.)

avatar image ProjectCryken · Jul 06, 2013 at 10:50 PM 0
Share

Ok, so how do I do this by adding forces?

avatar image wibble82 ProjectCryken · Dec 15, 2015 at 04:13 PM 0
Share

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!

3 Replies

· Add your reply
  • Sort: 
avatar image
1

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.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Dec 15, 2015 at 03:47 PM 1
Share

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

avatar image
-1

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.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image wibble82 · Dec 15, 2015 at 04:09 PM 0
Share

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.

avatar image Fattie wibble82 · Dec 15, 2015 at 04:11 PM 0
Share

Sometimes the clutter is overwhel$$anonymous$$g

avatar image
-1

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

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Dec 15, 2015 at 04:08 PM 0
Share

"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

avatar image wibble82 Fattie · Dec 15, 2015 at 04:23 PM 0
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges