Search Unity

Help, my rigidbodies have insomnia!

Discussion in 'Editor & General Support' started by Ostagar, Nov 16, 2010.

  1. Ostagar

    Ostagar

    Joined:
    Sep 29, 2010
    Posts:
    445
    I have a physics sim involving rolling balls on a flat surface. The problem is, they keeping rolling, rolling, rolling. Friction and drag slows them, but they never stop. Setting sleepVelocity = sleepAngularVelocity = 3 didn't help. Forcibly calling rigidbody.Sleep() also failed to stop them and never caused IsSleeping() to be set true. Ultimately, I wrote a custom VelocityMonitor script and applied it to each ball:

    Code (csharp):
    1. public class VelocityMonitor : MonoBehaviour {
    2.    
    3.     public enum BallStates { starting, rolling, slowing, sleeping };
    4.     public BallStates myState = BallStates.starting;
    5.        
    6.     public void FixedUpdate() {
    7.  
    8.         float velocity  = rigidbody.velocity.magnitude;
    9.         float threshold = 0.5f;
    10.        
    11.         switch ( myState ) {
    12.         case BallStates.starting:
    13.             if (velocity > threshold) {
    14.                 myState = BallStates.rolling; Debug.Log("rolling");
    15.             }
    16.             break;
    17.         case BallStates.rolling:
    18.             if (velocity < threshold) {
    19.                 myState = BallStates.slowing; Debug.Log("slowing");
    20.                 rigidbody.isKinematic = true;
    21.             }
    22.             break;         
    23.         case BallStates.slowing:
    24.             if ( rigidbody.IsSleeping() ) {
    25.                 myState = BallStates.sleeping; Debug.Log("sleeping");
    26.             }
    27.             break;         
    28.         case BallStates.sleeping:
    29.             break;
    30.         }
    31.     }
    32.    
    33. }
    While this stops them and puts them to sleep, it doesn't explain why sleepVelocity sleepAngularVelocity Sleep() weren't working for me. Was I missing something, or is this a bug? Shouldn't a good physics simulation that takes into account friction and drag eventually come to a rest on its own?

    Bonus: What's your favorite source for learning about Unity physics besides the user docs?.
     
    Last edited: Nov 16, 2010
  2. lulz

    lulz

    Joined:
    Oct 30, 2010
    Posts:
    7
    try to set the angular drag of the ball's Rigidbody to 11 try again if it didn't work try to tweak the project physic settings .... physics in unity drove me nuts a wail ago :D welcome on board ;)
     
  3. Ostagar

    Ostagar

    Joined:
    Sep 29, 2010
    Posts:
    445
    That was the trick! With angularDrag=4, dynamicFriction=0.5, and frictionCombine=Average the ball stops rolling without any scripting! http://www.youtube.com/watch?v=S_akRVW_v5k :)

    Although, there are still a couple loose ends:

    If angularDrag=0, dynamicFriction=1, and frictionCombine=Maximum the ball never stops rolling, so Unity's doc seems slightly inaccurate. dynamicFriction can severely slow down an object but drag is needed to actually bring it to rest.

    And Sleep(), sleepVelocity, and sleepAngularVelocity didn't work in my sim.
     
  4. Ostagar

    Ostagar

    Joined:
    Sep 29, 2010
    Posts:
    445
    Eric explained in another thread (another person, similar issue) why friction doesn't help in this scenario:

     
  5. Ostagar

    Ostagar

    Joined:
    Sep 29, 2010
    Posts:
    445
    Also on the Bullet Physics Library forum I found this:

     
  6. andre-ivankio

    andre-ivankio

    Joined:
    Mar 29, 2010
    Posts:
    53
    On this topic, I understand the benefits of angular drag to reduce speed. But I don't get why the rigidbody does not sleep when bellow the thresholds set for sleep velocities.

    $unity_Q01.png
    - ATM: 10 unity units = 10 cm. A ball is 6 in diameter, gravity = -100 (-980 would make it much less likely to sleep), timestep = 0.005

    I'm using Antares Universe (VIZIO) to retrieve the values but I assume it's pretty readable even if you are not familiar with it. Upper node calls (red outline) the second link, which indicates that "isSleeping" is false.

    The screenshot displays the read values for the the black ball (cue_ball). At the moment, it had no forces applied on it (except gravity). As "sleep velocities" are single floats, I'm assuming they are actually "sleep speeds". Anyway, the magnitude for velocities are also read bellow the thresold.

    It does eventually comes to sleep when velocities are near 0.0000001. But why won't it sleep as suggests
    http://unity3d.com/support/documentation/Components/RigidbodySleeping.html ?

    One could point that either gravity, bounce or penetration is the culprit; but even if gravity=0 it wouldn't work; bounce threshold is quite high already (1) and again, even on 100 won't work with the thresholds; and if I go to the extreme of burying the balls 3 cm in the table with min penetration, it will in fact be more unlikely to sleep never reaching 1e-7.

    I could work around it and manually check velocities and force sleep, but this would introduce computation that is theoretically already happening in the physics engine and I want to know what to expect from it.
     
    Last edited: Nov 1, 2011
  7. lopemanc

    lopemanc

    Joined:
    Feb 1, 2013
    Posts:
    2
    I wonder if there is anything new on this issue. I am just starting with Unity and I am experiencing this sleep issue. I have created a scrip that does the same thing, but that seems silly. I tried searching for the same issue in PhysX outside Unity and I can't find any report of the issue. That seems to imply that Unity is just not mapping the linear and angular sleep velocities correctly.
     
  8. wlad_s

    wlad_s

    Joined:
    Feb 18, 2011
    Posts:
    148
    Hi guys, try setting a "default material" property in "Physics Settings" to some physic material.

    It solved my problem even when I put a physic material with no friction at all.