Search Unity

isKinematic=false, strange penetration behaviour

Discussion in 'Physics' started by Ryukai3, Dec 31, 2018.

  1. Ryukai3

    Ryukai3

    Joined:
    Mar 30, 2017
    Posts:
    30
    Hi guys,
    as the title say, In Unity 2018.3 I have noticed a strange behaviour when a rigidbody has been set from iskinematic= true to isKinematic=false from script.

    In short, I have some rigidbodies stacked, settings like this:
    upload_2018-12-31_11-51-30.png

    Rigidbodies stacked:
    upload_2018-12-31_12-46-51.png

    Now, I have a script coroutine that set (at certain conditions, example collision with other rigidbodies or when a rigidbodies "has to fall") UseGravity= true, and IsKinematic = false.

    This is the coroutine:

    Code (CSharp):
    1. IEnumerator ActivateGravityCoroutine() {
    2.             rb.velocity = Vector3.zero;
    3.             rb.angularVelocity = Vector3.zero;
    4.  
    5.             if (rb.isKinematic == true) {rb.isKinematic = false;}
    6.             if (rb.useGravity == false ) {rb.useGravity = true; }
    7.  
    8.             rb.WakeUp();
    9.  
    10.         yield return new WaitForFixedUpdate();
    11.  
    12.     }
    Here is where the strangte behavior begin: once activated, not immediately, some rigidbody start to penetrate each other, like this (physic debug screenshot):
    upload_2018-12-31_13-1-44.png


    And after that, they jump wildly away.
    I have tried some thing but whit no success:
    • Increasing fixed timestep
    • Increasing Drag value
    • Adaptive force on/off
    • Broadbase type: multibox or sweep & prune
    • Changing Default contact offset
    • Changing Bounce Threshold
    • Changing solver iteration / velocity iteration
    • Disablinng/Enabling Auto sync transform
    • Interpolate/Extrapolate
    • Collision Detection : continous, ecc.
    • ...

    I hope I have detailed the problem exhaustively.
    Any help? :)

    Thank you!
     
    Last edited: Dec 31, 2018
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Are they moved only by gravity or are you doing any in-code manipulations?

    also, just pointing out that this:
    Code (CSharp):
    1. IEnumerator ActivateGravityCoroutine() {
    2.             rb.velocity = Vector3.zero;
    3.             rb.angularVelocity = Vector3.zero;
    4.             if (rb.isKinematic == true) {rb.isKinematic = false;}
    5.             if (rb.useGravity == false ) {rb.useGravity = true; }
    6.             rb.WakeUp();
    7.         yield return new WaitForFixedUpdate();
    8.     }
    has no reason to be a coroutine, you only do the "WaitForFixedUpdate" after the rest of the code runs, I say either make it a normal function or move the yield to the top.
     
  3. Ryukai3

    Ryukai3

    Joined:
    Mar 30, 2017
    Posts:
    30
    Hi SparrowsNest!
    Thanks for your reply!

    Yes, they are moved only by gravity when they are "activated". When they are "not activated", they do not receive any sort of manipulation programmatically.

    Thanks for this. Btw, tried moving yield on the top or making it a normal function but the problem of penetration still remain.


    As a side note , I think I figured out how to solve my problem.
    By modifying a setting in "Physics Settings":
    Before the Contact Pairs Mode was "Default Contacts Pairs". Now, when i set "Enable Kinematic Kinematic pairs", it seems to solve the weird penetration issue...at cost (I think) of more CPU work.
    upload_2019-1-3_16-39-10.png

    Now, I don't know why this setting solved my problem... Isnt this settings meant only for generate more collision calls, even between two kinematic rigidbodies?
    I don't understand how this setting can modify how two rigidbodies penetrate each other...
     
  4. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    On the first call, it will execute whenever, and then on subsequent iterations, it will be after the physics simulation.
    So it may not be what is intended, but it is worth noting that changing to FixedUpdate will have different results.
    I am not sure why WaitForFixedUpdate() executes after the physics simulation, but I am sure that there is a valid justification ;)
    My guess would be that something is turning off the isKinematic flag.