• 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
1
Question by PandrPi · Feb 07, 2020 at 12:53 PM · movementphysicsrigidbodyplayercontroller

A simple solution for constant rigidbody movement without changing and clamping velocity directly

Hello, I'm studying Unity game development about 5 years, but I had about 2-3 atempt for all these time of writing player controller and they were very simple, so yesterday i started to write own player movement system. From just a beginning I ran into a problem what to use to achieve the result I want. In Unity there are two most popular ways to write player controller: CharacterController and Rigidbody. I realised that the first don't fit to me because CC does not interact with other rigidbodies by default and is not very "physically realistic". So I choosed the rigidbody. Those people, who worked with RB( rigidbody ) may know about very cool method as AddForce and similar. But the main reason because of whith this method doesn't fit for movement( in some cases ) is that it will always accelerate a rigidbody, no "constant" movement speed, so someone can think that we need to limit the speed and will write something like this:

 void FixedUpdate()
     {
             var targetVelocity = someMoveDirection.normalized * speed;
             Vector3 velocity = rig.velocity;
             Vector3 velocityChange = (targetVelocity - velocity);
             velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
             velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
             velocityChange.y = 0;
             rig.AddForce(velocityChange, ForceMode.VelocityChange);
     }

But such a code will always limit your rigidbody's velocity to maxVelocityChange variable which is completely wrong way! Try to throw an massive rigididbody with enough speed into player and you will understand what I'm talking about. The result will be, for example, that player with mass 1 and speed 0 will stop some RB with mass 1000 and speed 500..

So I decided to return to AddForce method and look again what is wrong and how it can be resolved. I wanted to limit only the speed of my horizontal movement but not the velocity of RB in total. And one brilliant but at the same time simple thought came to my mind. How about adding as much force as it needed to keep the magnitude of RB's velocity "constant"? But how to reach that? The solution is very simple!

 var targetVelocity = someMoveDirection.normalized * speed;
 Vector3 horizontalVelocity = rig.velocity;
 horizontalVelocity.y = 0.0f;
 myRB.AddForce(targetVelocity * (1 - (horizontalVelocity.magnitude / maxMovementSpeed)));

As the result I just not add force to my RB if the speed is max. I hope it will help many people! :D

P.S. I am always open to any critique. if I wrote something wrong, you always can write bellow what is incorrect.

Comment
Add comment · Show 2
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 Bunny83 · Feb 08, 2020 at 02:57 AM 0
Share

Yes, you did something wrong ^^. You included the answer in your question. Please post an actual answer to your question and remove the answer from the question ;)


Note that your solution is not complete / has a nasty bug. If the player gets pushed / accelerated into one direction faster than your max$$anonymous$$ovementSpeed, then this term

 (1 - (horizontalVelocity.magnitude / max$$anonymous$$ovementSpeed))

will get negative. Now if the player presses the button in the opposite movement direction he can accelerate infinitely since your targetvelocity (which is not a velocity but a force) is applied in the current movement direction. So as a result you will get even faster. This makes the term above even more negative. The larger it gets the more force you can apply. It would be somewhat similar to the accelerated back hop glitch in the Source engine, though different.


Also you could replace horizontalVelocity.magnitude / max$$anonymous$$ovementSpeed with

 horizontalVelocity.sqr$$anonymous$$agnitude / (max$$anonymous$$ovementSpeed*max$$anonymous$$ovementSpeed)

That way you get rid of the square root and you get a slightly better result as the applied force will not be reduced linearly but quadratic. So your code does apply 50% force when you are at half the velocity. Using the squared magnitude you will apply 75% of your force. So it stays longer closer to 1 and only drops to 0 when you get close to your max velocity.


In addition you could just multiply the (1 - sqr$$anonymous$$ag/maxSpeed) term by an arbitrary factor greater than 1 to introduce a "hold" phase. Since we now use $$anonymous$$athf.Clamp01 we will always get a value between 0 and 1. However since the term inside will be greater than 1 even we have not yet reached the max velocity we get a resulting factor of 1 for a longer time. So for example if you multiply by a factor of 2, at half the velocity you would still apply the full force.


Well this is all just basic math and actually a crude version of a PID controller with only a linear (proportional) part. andeeeee wrote a simple PID controller class almost 10 years ago if someone is interested.

[2]: https://docs.unity3d.com/ScriptReference/$$anonymous$$athf.Clamp01.html

avatar image SpatenDeamon · Feb 02, 2021 at 11:09 AM 0
Share

What is the different between the rigidbody myRB and rig?

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Reid_Taylor · Feb 08, 2020 at 01:53 AM

Also if you don't wanna go through the trouble you can use rigidbody.velocity = transform.TransformDirection(Vector3.(left, right, back or forward) * speed).

Comment
Add comment · 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
0

Answer by PandrPi · Feb 18, 2020 at 12:07 PM

@Bunny83 Yes, sorry, I just forgot to write clamp the value. And yes, this post is not a question, it is something like discussion for reaching simple movement :)

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 PandrPi · Feb 18, 2020 at 12:13 PM 0
Share

Also I found out that if do like I wrote here the result will be that player will move like on ice in some cases.

So now I use rigidbody.$$anonymous$$ove method in FixedUpdate to move the player.

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

277 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Character controller jittering up and down 2 Answers

Player is Speeding up in collisions 0 Answers

Rigid body child Player movement 0 Answers

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Issues Making Character Move With Rigidbody 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