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
4
Question by platf2 · Oct 28, 2014 at 06:03 PM · c#movementphysicsrigidbody

Force to Velocity scaling?

I am using rigidbody.AddForce() to move my player in FixedUpdate(), and I have noticed that "force added" -> "object velocity" doesn't scale linearly. So when I add a force of, let's say 10, to the Z-axis, it will reach a velocity of 4 units/second after some time, but when I add half the force it doesn't move at half the velocity, instead it moves at a speed much much slower.

I would like to be able to find the correct force to apply in order to accurately scale my speed up or down. I know an alternative is to use rididbody.velocity to execute movement or to clamp speed to a limit, but I would much rather be able to find the correct force to apply. So does anyone happen to know the correct formula necessary to achieve this, or maybe know of a way to make the force to velocity scale in a way I can accurately control it?

Thanks!

Edit: I am using Drag of 1 which is causing the scaling to not be linear, and I would prefer not to disable the drag because it makes sure my object doesn't keep accelerating. Are there any formulas that include drag? I think that might be what I need.

Comment
Add comment · Show 6
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 robertbu · Oct 28, 2014 at 06:13 PM 0
Share

Unity uses standard physics, so you should be able to use the standard physics calculations you will find many places on the net. If you want to control velocity precisely, simply assign directly to Rigidbody.velocity.

avatar image platf2 · Oct 28, 2014 at 06:59 PM 0
Share

I'm unable to find the formula/answer anywhere on the internet, and I wrote that I knew about rigidbody.velocity but would prefer not to use it.

avatar image Itaros · Oct 28, 2014 at 07:04 PM 0
Share

velocity = force / mass ?

avatar image platf2 · Oct 28, 2014 at 07:14 PM 0
Share

That formula doesn't work in this case, if it did then "force added" -> "object velocity" would scale linearly, and I wrote that that it didn't.

avatar image Bunny83 · Oct 28, 2014 at 08:09 PM 1
Share

Is it possible that you have a drag value setup on your rigidbody? The drag force will increase the faster you move. That means if you use only half the force to drive your rigidbody you don't have enough power to fight against the drag.

Theoretically if there's no drag at all you will accelerate linearly and your velocity will grow infinitely.

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
13

Answer by Bunny83 · Oct 28, 2014 at 07:58 PM

You might want to read my answer over here

edit
In addition to my answer about how AddForce actually works, here's how the drag is applied (at least in version 4.5.4f1):

 velocity *= Mathf.Clamp01(1f - drag * Time.fixedDeltaTime);

You might want to read my post on the forum where i explain it a bit more in detail.

second edit
If you want to use Unity's drag system, here are 6 helper methods to calculate:

  • the final velocity you might reach for a given acceleration / velocityChange and drag value.

  • the drag value required for a given acceleration / velocityChange to reach the desired velocity.

  • the acceleration / velocityChange required to reach the desired velocity with a given drag value

You could extend each pair of methods to work with an actual force / impulse value. Keep in mind those methods only work for an acceperation / velocity change applied each FixedUpdate. One-time changes are pointless since you will have the final velocity at the moment you apply the force / acceleration / change. The drag will simply pull it back to 0.

 //C#
 float GetFinalVelocity(float aVelocityChange, float aDrag)
 {
     return aVelocityChange * (1 / Mathf.Clamp01(aDrag * Time.fixedDeltaTime) - 1);
 }
 float GetFinalVelocityFromAcceleration(float aAcceleration, float aDrag)
 {
     return GetFinalVelocity(aAcceleration * Time.fixedDeltaTime, aDrag);
 }
 
 
 float GetDrag(float aVelocityChange, float aFinalVelocity)
 {
     return aVelocityChange / ((aFinalVelocity + aVelocityChange) * Time.fixedDeltaTime);
 }
 float GetDragFromAcceleration(float aAcceleration, float aFinalVelocity)
 {
     return GetDrag(aAcceleration * Time.fixedDeltaTime, aFinalVelocity);
 }
 
 
 float GetRequiredVelocityChange(float aFinalSpeed, float aDrag)
 {
     float m = Mathf.Clamp01(aDrag * Time.fixedDeltaTime);
     return aFinalSpeed * m / (1 - m);
 }
 float GetRequiredAcceleraton(float aFinalSpeed, float aDrag)
 {
     return GetRequiredVelocityChange(aFinalSpeed, aDrag) / Time.fixedDeltaTime;
 }

Final note: In case a constant force is applied with a drag value > 0, the velocity will slowly get closer to the final velocity but won't actually reach it. However due to floating point precision the remaining difference will usually be "rounded away" within seconds.

Also keep in mind that in case your drag value is greater than the fixed framerate, functions like GetRequiredAcceleraton will return infinity as there is no acceleration to reach the given speed.

Comment
Add comment · Show 11 · 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 Kiwasi · Oct 28, 2014 at 10:36 PM 1
Share

We should probably add that answer to the docs.

avatar image platf2 · Oct 28, 2014 at 10:41 PM 0
Share

Thanks, I know how the forcemodes work though and they are not part of the solution. Your comment on my post got me realizing that I might need a formula which includes drag and how it affects the velocity.

avatar image Bunny83 · Oct 29, 2014 at 12:38 PM 0
Share

@platf2: I made a few tests and it seems the drag is calculated in a very strage way. I've updated my answer.

avatar image platf2 · Nov 08, 2014 at 01:07 PM 0
Share

@Bunny83

Sorry, I didn't check this post after my last replies because I thought nothing more would come. I just saw your edits though and your methods look very interesting. I've tried using them but I can't get them to work for me. Could you possibly tell me which one of them I'd have to use with what parameters in order to find the force I need to apply in rigidbody.AddForce() in order to reach a certain final velocity?

avatar image Bunny83 · Nov 08, 2014 at 02:37 PM 0
Share

@platf2: In this case you need GetRequiredAcceleraton. You have to pass your target velocity and the drag value of your rigidbody. $$anonymous$$eep in $$anonymous$$d that this will calulate the required acceleration. So when using AddForce you would have to use Force$$anonymous$$ode.Acceleration. If you want to use Force$$anonymous$$ode.Force (which is the default when you omit the parameter) you have to multiply the returned value with the mass of your rigidbody. Two examples:

     float targetVelocity = 20.0f;
     Vector3 dir; // the direction you want to move.

     Vector3 requiredAcc = dir.normalized * GetRequiredAcceleraton(targetVelocity, rigidbody.drag);
     
     // inside FixedUpdate
     // either use
     rigidbody.AddForce(requiredAcc, Force$$anonymous$$ode.Acceleration);
     // or
     rigidbody.AddForce(requiredAcc * rigidbody.mass);
Show more comments
avatar image
0

Answer by Kiwasi · Oct 28, 2014 at 07:20 PM

There's this guy called Newton? Maybe you've heard of him.

Anyway the correct formula is force = mass * acceleration.

There are lots of other formulas to try. Google Newtonian physics. Or classical physics.

Comment
Add comment · Show 4 · 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 Kiwasi · Oct 28, 2014 at 07:46 PM 0
Share

$$anonymous$$omentum and energy are two other terms that might be worth googling.

Basically everything you would find in a high school physics text book applies in Unity.

avatar image platf2 · Oct 28, 2014 at 10:44 PM 0
Share

I know of that formula, but I don't think I can apply it to this scenario. It doesn't include Drag, which is what causes the Force and Velocity not to scale linearly, so I think I need a formula which includes it.

Also, how would I go around finding the acceleration of my object?

avatar image Kiwasi · Oct 29, 2014 at 03:16 AM 1
Share
 Acceleration = change in velocity / time

So to accelerate a 1 kg object to 1 m/s in 1 s you need a force of 1 N. Double the force and you get double the acceleration. Hence double the speed in the same time.

Drag can be considered a force in the opposite direction to velocity with a magnitude proportional to velocity squared. Hence your observed non linearity.

Using drag to control the maximum speed of your objects is not a good idea. (Unless you are dealing with free fall through the atmosphere or movement inside a viscous liquid). By using high drag you are basically saying all of your objects are moving at ter$$anonymous$$al velocity. This is not overly realistic.

However if you want the formula:

 Ter$$anonymous$$al velocity is proportional to the square root of ( 2 * mass * Force / drag )

The proportionality constant depends on how PhysX has implemented drag. I'm pretty sure it will be one.

Edit: I hate typing formulas on I$$anonymous$$ The wiki pages for the various concepts I've described have proper looking formulas.

avatar image platf2 · Oct 29, 2014 at 09:35 AM 0
Share

Thanks Bored$$anonymous$$ormon, I learned a lot from that post. What I really would like to do though is leave the Drag at 1, not change it, but find a formula which takes drag in account when finding the force necessary to reach a certain velocity.

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

7 People are following this question.

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

Related Questions

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

Problem Trying to Apply Non-Kinematic Velocity to Rigidbody 0 Answers

Finding the axis of a curving pipe 0 Answers

Performance Question on Kinematic Rigidbodies 1 Answer

RigidBody.MovePosition seems jerky in movement 0 Answers


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