Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 /
This question was closed May 11, 2015 at 07:45 PM by AlwaysSunny for the following reason:

Question closed. This shouldn't have been resurrected to begin with.

avatar image
14
Question by Ehren · Jan 11, 2010 at 04:26 PM · physicsrigidbody

Limiting rigidbody velocity

When working with non-kinematic rigidbodies (especially bouncy ones), there can be situations where collisions with static colliders and other rigidbodies result in large increases in velocity. This can lead to undesirable effects, such as objects suddenly "teleporting" to random parts of the screen or breaking through static collider scenery.

What's the best way to limit the velocity of a non-kinematic rigidbody?

Comment
Add comment · Show 1
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 dingben · Sep 17, 2010 at 07:38 AM 0
Share

Could someone take a look at my post and let me know if this thread is really one and the same issue? You only mention collisions with known objects in this thread... in my scenario I have no collisions with known objects except, if any, the terrain itself... and also do see in my post that it happens while vehicle is at complete idle. http://answers.unity3d.com/questions/20456/terrain-unexpected-collisions-loopidy-loops

7 Replies

  • Sort: 
avatar image
18
Best Answer

Answer by duck · Jan 11, 2010 at 04:40 PM

I can think of two methods of doing this, one of them is recommended against by UT though.

First, check the magnitude of your rigidbody.velocity][1].

If it's under the speed limit, take no action. If it's over the speed limit you can do one of two things:

  • The 'proper' way would be to apply a force in the opposite direction of the rigidbody's velocity. The amount of force should be proportional to the extent to which the rigidbody is exceeding its speed limit.

  • The naughty, non-recommended way would be to take the current velocity vector, and if its magnitude exceeds the speed limit, normalize the vector3, multiply it by the speed limit, and directly reassign the velocity vector.

I'm not entirely sure whether this second method comes recommended against just because of "non realism", or whether there could be more serious simulation-breaking consequences.

Comment
Add comment · Show 9 · 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 Ehren · Jan 11, 2010 at 05:18 PM 0
Share

Thanks, Duck. $$anonymous$$y current approach is to gradually increase drag as the velocity approaches the limit, and then use the second approach (normalize/multiply) to clamp it. I've noticed that the velocity can exceed the "speed limit" (instantaneously, in some cases) in FixedUpdate, OnCollisionEnter, or OnCollisionExit, so I'm checking it all three places. But this feels a bit heavy-handed and overly complex, not to mention sub-optimal from a performance perspective. Also, as you mention, I'm concerned I might be unintentionally creating some undesirable side-effects.

avatar image jonas-echterhoff ♦♦ · Jan 11, 2010 at 06:28 PM 4
Share

While this works (and I don't think directly changing the velocity here should pose a problem really), if you do this on a lot of objects, and in many places, consider checking against the sqr$$anonymous$$agnitude of the velocity ins$$anonymous$$d, as that is faster. $$anonymous$$ay not make much of a difference here, but it's always good practice.

avatar image alexpf · Mar 23, 2014 at 11:30 AM 6
Share

Wouldnt the $$anonymous$$ethod Vector2.Clamp$$anonymous$$agnitude(Vector2, float) or the Vector3 equivalent be an interesting alternative?

rigidbody.velocity = Vector3.Clamp$$anonymous$$agnitude(rigidbody.velocity, 10f);

avatar image liju · Apr 04, 2014 at 05:39 AM 0
Share

thank you

avatar image Leonach · Feb 16, 2015 at 05:54 PM 1
Share

How would you deter$$anonymous$$e the magnitude "speed limit" of a rigidbody? I am having difficulties with a ball that will break through colliders, and I can't deter$$anonymous$$e the speed at which it is doing so. I understand how to figure the magnitude of vectors, so that is not the problem. Simply deter$$anonymous$$ing the rigid body's maximum speed (the velocity at which it breaks through the colliders) is the difficulty.

Show more comments
avatar image
16

Answer by Ehren · Feb 02, 2010 at 05:31 PM

I just posted a couple scripts for limiting velocity, along with an example project, to my blog. Here is the script for Duck's proposed solution.

#pragma strict

// This MonoBehaviour uses hard clamping to limit the velocity of a rigidbody.

// The maximum allowed velocity. The velocity will be clamped to keep // it from exceeding this value. var maxVelocity : float;

// The cached rigidbody reference. private var rb : Rigidbody; // A cached copy of the squared max velocity. Used in FixedUpdate. private var sqrMaxVelocity : float;

// Awake is a built-in unity function that is called called only once during the lifetime of the script instance. // It is called after all objects are initialized. // For more info, see: // http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.Awake.html function Awake() { rb = rigidbody; SetMaxVelocity(maxVelocity); }

// Sets the max velocity and calculates the squared max velocity for use in FixedUpdate. // Outside callers who wish to modify the max velocity should use this function. Otherwise, // the cached squared velocity will not be recalculated. function SetMaxVelocity(maxVelocity : float){ this.maxVelocity = maxVelocity; sqrMaxVelocity = maxVelocity * maxVelocity; }

// FixedUpdate is a built-in unity function that is called every fixed framerate frame. // We use FixedUpdate instead of Update here because the docs recommend doing so when // dealing with rigidbodies. // For more info, see: // http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.FixedUpdate.html function FixedUpdate() { var v = rb.velocity; // Clamp the velocity, if necessary // Use sqrMagnitude instead of magnitude for performance reasons. if(v.sqrMagnitude > sqrMaxVelocity){ // Equivalent to: rigidbody.velocity.magnitude > maxVelocity, but faster. // Vector3.normalized returns this vector with a magnitude // of 1. This ensures that we're not messing with the // direction of the vector, only its magnitude. rb.velocity = v.normalized * maxVelocity; }
}

// Require a Rigidbody component to be attached to the same GameObject. @script RequireComponent(Rigidbody)

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 Bravini · May 06, 2011 at 06:24 PM 0
Share

nice blog too btw!

avatar image Develax · May 20, 2019 at 10:48 AM 0
Share

The logic and calculations are correct.

avatar image
10

Answer by A Square Fish · Dec 06, 2014 at 01:49 PM

The problem with doing the dirty example is defining the velocity of an object is against the physics system. It is like stopping the object from moving and sending it moving again.

Also cherub got us started on doing that every single processing frame, which is damage by your program to the physics engine! You would find yourself a lot better off using rigidbody.drag somehow, though I can't say that 100% is a good thing.

Here is my "definitive" answer to braking an object to a maximum speed:

 float speed = Vector3.Magnitude (rigidbody.velocity);  // test current object speed
      
 if (speed > maximumSpeed)
 
  {
      float brakeSpeed = speed - maximumSpeed;  // calculate the speed decrease
 
      Vector3 normalisedVelocity = rigidbody.velocity.normalized;
      Vector3 brakeVelocity = normalisedVelocity * brakeSpeed;  // make the brake Vector3 value
 
      rigidbody.AddForce(-brakeVelocity);  // apply opposing brake force
  }

Sorry Ehren, but I find your answer very unreadable on this page!

Comment
Add comment · Show 3 · 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 bracciata · Aug 23, 2015 at 01:00 AM 0
Share

Can you please help with translate to vector2 for a 2d game or would this work for a 2d game

avatar image A Square Fish · Aug 23, 2015 at 03:31 AM 0
Share

Hi bracciata.

$$anonymous$$y answer I've checked over and is not a fully working code in most circumstances. However it's close to a solution.

You may have noticed some are modifying rigidbody.velocity directly, which is known to stress the physics system and can slow down/affect badly the calculation processes. I am very against that! I think it is stated not to do this in the Unity reference?

To your question, you can convert all to Vector2 quite easily in this example, or use only Vector3 (x, 0.0f, z); if using a fixed Y plane. If using Z plane use only Vector3 (x, y, 0.0f)

There are other ways to cast out the 2 axis (2d) rather than 3 axis (3d). Simple?

 Vector3 position3d = new Vector3(1.0f, 1,0f, 0.0f); // A position 1,1 on the Z axis
 Vector2 position2d = position(position3d.x, position3d.y); // A conversion to Vector2

At least I hope that is a good advice for you.

avatar image Raunchard · Nov 07, 2015 at 12:28 AM 1
Share

the problem is that this approach doesn't take the mass into account.

avatar image
8

Answer by cherub · Apr 04, 2014 at 05:07 AM

i found that doing this was pretty simple and worked:

             if(rigidbody.velocity.sqrMagnitude > maxVelocity)
             {
                 //smoothness of the slowdown is controlled by the 0.99f, 
                 //0.5f is less smooth, 0.9999f is more smooth
                     rigidbody.velocity *= 0.99f;
             }
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 nicloay · Aug 23, 2014 at 11:55 AM 0
Share

wow, nice approach, just this works for me now. thanks, man!

avatar image KarlKarl2000 · May 28, 2020 at 01:04 AM 0
Share

O$$anonymous$$G... This was simple and works. In Cherub we trust! Thank you for such an elegant solution.

0.99 will still drop rigidbodies like meteorites, but between 0.5 and 0.999 u can definitely find a a sweet spot.

avatar image
0

Answer by Spiff McShizly · Jan 14, 2013 at 09:59 PM

here's how I did it quick & dirty:

 // clamp velocity:
 Vector3 newVelocity = rigidbody.velocity.normalized;
 newVelocity *= m_MaximumVelocity;
 rigidbody.velocity = newVelocity;
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 3itg · Mar 07, 2014 at 09:38 PM 1
Share

This was the best answer for me, only slightly modified (my game is 2d / c#).

         if($$anonymous$$athf.Abs(rigidbody.velocity.x) > maxSpeed || $$anonymous$$athf.Abs(rigidbody.velocity.y) > maxSpeed)
         {
             // clamp velocity:
             Vector3 newVelocity = rigidbody.velocity.normalized;
             newVelocity *= maxSpeed;
             rigidbody.velocity = newVelocity;
         }
  • 1
  • 2
  • ›

Follow this Question

Answers Answers and Comments

19 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

Related Questions

Why does this MeshCollider think it's half as thick? 2 Answers

Any way to have a rigidbody not be affected by forces, but still collide with other objects? 2 Answers

Physics gravity appears very weak 2 Answers

Rigidbody Moving around a tower 0 Answers

Turning a rigidbody controller into a character controller (almost) 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