Search Unity

Physics bug unfixed for almost 2 years?

Discussion in 'Physics' started by Plystire, Dec 17, 2016.

  1. Plystire

    Plystire

    Joined:
    Oct 30, 2016
    Posts:
    142
    My recent bug report has been closed as duplicate of:
    https://issuetracker.unity3d.com/is...set-child-colliders-produces-unstable-results

    If it doesn't bother anyone, can I please ask that others upvote this bug for fixing? I am currently making a zero-G VR game, and this bug is absolutely game breaking for my project. :(
    [EDIT clarification]
    https://forum.unity3d.com/threads/zero-gravity-issue-with-vr-rig.444280/#post-2873828

    I was told in the support response email that my findings would assist with the bug fixing. I hope so. And I hope maybe we can encourage them to take a harder look at it sooner, before another half of a version goes by. :)
    [EDIT2]
    This bug has been active since Feb 2015. Since Unity 5.0.0 Priority 3. Severity 0. Are you kidding me with severity 0? What the hell is wrong with the physics engine that after a few minutes in my game, the player is vibrating at a magnitude of ~10% their body width? This is game breaking, it's stupidly easy to replicate, and it's sad to see that if I don't act the sqeaky wheel, it will probably never get fixed. :p
    [EDIT3]
    Replication clarification:
    1) New Scene
    2) Empty GameObject
    3) Attach Rigidbody, turn off Gravity
    4) Attach child sphere (with collider)
    5) Hit Play
    6) In SceneView, select the parent object for inspection and observe ZERO MOVEMENT
    7) Select child sphere
    8) Move child in local space however you wish. Slide it up and down an axis a few times, that's all it takes.
    9) Select parent object again and observe NEW NON-ZERO LOCATION with ZERO MOVEMENT
    (Having a second child object for visual reference of parent object's location also helps to view the randomness and increasing intensity over time)

    Thank you for your attention!

    Again, if you're still reading, please go to the link below and VOTE to have it fixed please! :)
    It takes only 2 seconds if you're logged in, maybe 15 if you're not and you have an account.
    https://issuetracker.unity3d.com/is...set-child-colliders-produces-unstable-results




    Go do it ;)

    [EDIT4.8]
    And if you don't have an account, you should totally go sign up! It's free and easy! And then you can post here about how much you agree with me that it's absolutely ridiculous that this bug hasn't even had its severity level defined in almost 2 years!!! Half of a version has gone by since then! D:
    [EDIT5.5]
    Post about how their support team had the nerve to close my legitimate bug report because it's a duplicate of a bug that they didn't even want to look at!

    [EDIT6.1]
    https://issuetracker.unity3d.com/is...set-child-colliders-produces-unstable-results
    Vote it! Now! If we build enough votes, I can go harass them instead of you guys. ;)

    Happy Holidays! :)
     
    Last edited: Dec 21, 2016
  2. Dennis_eA

    Dennis_eA

    Joined:
    Jan 17, 2011
    Posts:
    380
    You say, you are 'scaling rigidbodies'.
    I bet there is a 'work around', a (better) way to avoid scaling a rigidbody (itself).
    What are you trying to achieve?
     
  3. Plystire

    Plystire

    Joined:
    Oct 30, 2016
    Posts:
    142
    I am not scaling a rigidbody. I am simply translating a child collider in local space. "My recent bug report has been closed as duplicate of:" The original author of the bug report I have linked was scaling.

    [EDIT2]
    I see you didn't vote. C'mon, man. You already opened the link. It only takes 2 more seconds to click on the vote button. You're most likely already logged in so... you should totally go do that now. ;)

    [EDIT3]
    Moved edits to first post for better context
     
    Last edited: Dec 17, 2016
  4. Marc-Saubion

    Marc-Saubion

    Joined:
    Jul 6, 2011
    Posts:
    655
    Why don't you make the child kinematic?
     
  5. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    I got some potential good news.

    I did a quick test and was able to reproduce the issue, while also finding a fix and possible cause of the issue, which is the rigidbody centerOfMass.

    When you move a child collider of a rigidbody, unity will automatically change the rigidbody center of mass, which seems to cause this change in the rigidbodies position possibly due to floating point error?

    Here is my test script
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class TestRigidbodyCenterMassBug : MonoBehaviour
    5. {
    6.     public bool setCenterOfMass;
    7.  
    8.     Rigidbody myRigidbody;
    9.     Transform child;
    10.  
    11.     void Awake()
    12.     {
    13.         myRigidbody = GetComponent<Rigidbody>();
    14.         child = myRigidbody.transform.GetChild(0);
    15.  
    16.         //Setting a rigidbody center of mass tells unity not to automatically set it
    17.         //when detecting changes in the rigidbody, such as a child collider moving.
    18.         //This alone is enough to fix the bug.
    19.         if(setCenterOfMass)
    20.         {
    21.             //We set the center of mass to itself just to stop unity from automatically setting it.
    22.             //To get unity to start automatically setting it again, you need to call myRigidbody.ResetCenterOfMass()
    23.             myRigidbody.centerOfMass = myRigidbody.centerOfMass;
    24.         }
    25.     }
    26.  
    27.     void Update()
    28.     {
    29.         child.Translate((Vector3.up + Vector3.left) * .1f);
    30.         Debug.Log("Center Mass After Translate  = " + DetailedVector(myRigidbody.centerOfMass));
    31.     }
    32.  
    33.     string DetailedVector (Vector3 vector)
    34.     {
    35.         return "(" + vector.x + ") (" + vector.y + ") (" + vector.z + ")";
    36.     }
    37. }

    If we use your example setup of having a empty gameobject with a rigidbody component and no gravity placed at the origin (0,0,0), and add a child sphere object with a collider, place this script on the empty gameobject with the rigidbody on it.
    If setCenterOfMass is on, we will set the center of mass on awake, which basically tells unity to not automatically update the center of mass for us and you will notice the empty gameobject no longer jitters.
    If setCenterOfMass is off, you will notice the debug logs showing the center of mass is changing due to the child object being translated, which seems to also cause the empty gameobject to jitter.

    You can see unity talk about some center of mass stuff here
    https://docs.unity3d.com/ScriptReference/Rigidbody-centerOfMass.html
     
    Plystire likes this.
  6. Plystire

    Plystire

    Joined:
    Oct 30, 2016
    Posts:
    142
    This is very handy information. Thank you for posting! :)

    Unfortunately, when I implemented this, I found two problems.
    1) On load, the rig is jittering already, and this did not fix it. I had to collide with another object before the jittering stopped. Though, it did indeed appear to remain stopped, unlike before.
    2) The rig no longer rotates around the player's head.... which poses a smaller problem in itself, but we may be able to deal with that.

    Being this is VR, the rotations now feel as though they occur around some arbitrary point in nearby space. :( I thought about how I could circumvent this without allowing Unity to do its thing. Perhaps maybe reset the center when the player begins rotation, and also when colliding with something... I have my doubts about the accuracy of doing it this way, but I'll edit post after giving it a go.

    Before implementing this, the jittering would increase in magnitude over time. Now it does not seem to. When colliding with an object, the jittering intensity resets to 0 (But as I said above, the jittering seems to begin even before the Awake function is called), though because it increases over time, it will eventually pick back up to obnoxious levels over a minute or so.

    [EDIT]
    A crazy thought just occurred to me. Do you suppose this jittering is actually part of some kind of "unstuck" system or the sort? It makes sense that the jittering will occur when the object is created if they have some kind of underlying system that moves the object around until it finds the "floor" maybe? Then when the child collider moves causing the center of mass to shift and the rigidbody to reinitialize physics, it just does it again because init? And maybe the logic simply adds to the current jiggle rate when it's called, thus the steadily increasing intensity from being called repeatedly?

    If that were the case, we just need a way to turn that behavior off somehow.

    [EDIT2]
    I see you didn't vote either. Is literally everyone out of votes or something? Or does no one really care if the engine gets fixed or not? Not one of the current 140 views actually bothered to help out. 0/140... that's not very encouraging, community. :(

    [EDIT3]
    Code (csharp):
    1.  
    2.     void Awake()
    3.     {
    4.         rig = GetComponent<Rigidbody>();
    5.         if (rig == null)
    6.         {
    7.             throw new System.Exception("[PlayerController] Player Rig initialized without Rigidbody!");
    8.         }
    9.  
    10.         Debug.Log("Setting center of mass");
    11.  
    12.         // Set center of mass to itself so we prevent Unity from constantly trying to recalculate it
    13.         rig.centerOfMass = rig.centerOfMass;
    14.     }
    15.  
    16.     void FixedUpdate()
    17.     {
    18.         // If we have any sort of angular velocity, reset center of mass (and center of rotation) to the player's head every so often.
    19.         //if (rig.angularVelocity.sqrMagnitude > 0.0001f && Time.time > resetCoMTime)
    20.         if (Time.time > resetCoMTime)
    21.         {
    22.             // Reset center of mass to player's head. (Doing this manually since this causes an error-prone update to the rigidbody, and automatic updates will cause a massive jitter)
    23.             rig.ResetCenterOfMass();    // This turns on auto-update as well
    24.             rig.centerOfMass = rig.centerOfMass;    // Turn off auto-update for center of mass
    25.  
    26.             Debug.Log("Reset CoM");
    27.  
    28.             // Reset CoMTime
    29.             resetCoMTime = Time.time + 0.5f;    // Wait another so often
    30.         }
    31.     }
    32.  
    Results of experiments:
    - The rig is always jittering when the scene loads.
    - Colliding with something will make the jittering stop
    - Resetting center of mass seems to do absolutely nothing to stop jittering
    - Applying angular velocity stops the jittering (which... come to think of it, might be correlated to collisions... since they would apply angular velocity)
    - After angular velocity dies down... the rig will begin to jitter noticeably after ~1 minute and 20 seconds.
    - Changes in velocity do not effect jittering
    And best of all:
    - Removing the above code results in zero difference in behavior.

    I have angular drag = 0.01, so perhaps the 20 seconds is what it takes for the drag to fully stop the rigidbody's angular velocity, and it's actually 1 minute until the jittering begins?
    In any case, center of mass does not seem to be effecting my rig the way I thought it was.

    Hmmm, perhaps this is a different bug after all? :confused:

    For clarification:
    When I say "not jittering anymore", I actually mean the jittering has sunk to a level of ~0.000001f in constant positional movement... effectively immobile for all intents and purposes.
    When I said "begin to jitter noticeably", I meant that the jittering suddenly rose to a level of ~0.001f in constant positional movement, and slowly increasing from there... effectively not only visible, but very disruptive in VR.

    [EDIT4]
    Changed code to:
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class AntiJitter : MonoBehaviour {
    4.  
    5.     public Rigidbody rig;   // Rig to apply anti-jitter to
    6.  
    7.     private float tickTime = 0.0f;  // Time at which antijitter is applied
    8.     private float tickSpeed = 0.00001f; // Very slight bump
    9.    
    10.     void FixedUpdate ()
    11.     {
    12.         // Every so often, we must prevent jitter
    13.         if (Time.time > tickTime)
    14.         {
    15.             // Apply unnoticeably slight nudge to angular velocity to stop rig jittering bug
    16.             Vector3 corr = rig.angularVelocity;
    17.             corr.x += tickSpeed;
    18.             tickSpeed *= -1;    // Apply opposite nudge next time
    19.             rig.angularVelocity = corr;
    20.  
    21.             // Reset tickTime
    22.             tickTime = Time.time + 59.0f;    // Wait another so often
    23.         }
    24.     }
    25. }
    Every 59 seconds I apply a tiny boost to angular velocity. No more jittering... waited 10 minutes and the rig never budged (a noticeable amount... the noise of 0.000001f movements was still there, which over 10 minutes accumulated to a noticeable size, but not over a short period)

    What a strange phenomena. I will open a new bug report for this. It is clearly not the same bug as demonstrated with the sphere... I'll have to work on actual replication steps for it...
     
    Last edited: Dec 23, 2016