Search Unity

Bug Breaking Parental Relationship Alters Parent's Position

Discussion in 'Physics' started by MrBigly, Jun 8, 2023.

  1. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    221
    I have a character that has assets (various types of grenades) attached to it. While attached, the assets are disabled (not active), thus they are hidden from view and simply parented to the character game object.

    Each of the assets is different in some way to the others. Two use sphere colliders, two use capsule colliders. But they all have rigid bodies with identical parameters.

    When throwing the assets, the asset is activated, detached from the character, and given a force against the rigid body to send it into flight.

    But I found an interesting behavior I think is a bug.

    In the case of the first asset, it simply works as expected. In the case of the other three, the character game object is positioned into the air as though it jumped up, and it falls back to the ground as the asset flies forward from the character.

    What is really strange is that I tweaked some parameters for the other three asset prefabs and two of them ceased demonstrating this behavior. The parameters typically were the scale value on their transform and should have nothing to do with physics. I made additional tweaks and the problems came back.

    I have no idea what is happening, but I narrowed the problem to the two lines of code:

    Code (CSharp):
    1.  
    2.         // Enable the GameObject for this prefab so that it is visible.
    3.         gameObject.SetActive(true);
    4.  
    5.  
    6.         // Break parent-child relation...
    7.         transform.parent = null;
    8.  
    It doesn't matter which line comes first, it is the combination of these two lines that seem to lead to the problem manifesting. If I only have these two lines of code when dropping a grenade (no forward force applied to the asset), then the character jumps up and then lands on the asset (grenade), which fell to the ground when the character was up in the air.

    Any ideas or insight would be appreciated.

    ------

    EDIT: This code was executed in the context of FixedUpdate() in response to user input and network traffic. I moved all but the SetActive(true) statement into Update() and the problem went away. Since the internal physics engine runs between FixedUpdate() and Update(), it would seem to confirm that the physics engine cannot properly handle the game object active state going back to active and the parent transform reference changing in the same pass.
     
    Last edited: Jun 9, 2023
  2. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    221
    I found the problem, it was the collider of the Asset I was orphaning was forcing the collider of the Pawn up above it. Even when I was positioning it far ahead of the Pawn, the physics engine seemed to think the position update wasn't applicable.

    The solution was to disable the collider, break the parental relationship, enable the Asset, position it, and apply a velocity to it all in the context of FixedUpdate, then enable the collider in Update(), after the physics engine processed the Asset's new state.

    I still think this is a bug in the physics engine. It should recognize that the position of the Asset's collider is not within the Pawn's collider any longer.
     
  3. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    453
    When objects are in the same hierarchy, the colliders act together as a bunch and don't push each other. If you deparent the child object, the evident thing will happen which is the colliders start acting like there's two separate objects now.

    ps. when you say "Asset", this doesn't correcly specify what you are doing. Assets are resource bundles (files) in your project folder, but what your game works with is gameobjects, transforms, rigidbodies, colliders and such. So instead of "orphaning an asset" you are deparenting a gameobject's transform. Transform is the gameobject's dimensions and also the part that forms the hierarchy structure. Rigidbody and colliders are components on your gameobject. They are structured like this in Unity, and they translate to PhysX respective elements under the hood.

    So before blaming the physics engine, make sure you first understand these concepts, because it could be more likely that you are just not in full awareness of what you are doing.
     
    Last edited: Jul 13, 2023
  4. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    221
    Ya, i think it is a bug in the physics engine. This only happens when the GameObject is switched from disabled to enabled AND orphaned from its Parent in FixedUpdate(). It should not happen at all since the GameObject is moved far enough away that the colliders are no where near each other. Yet it does in this scenario.

    As an aside, I tried another experiment where I orphaned and enabled the GO after I positioned it away from the Parent GO so the colliders don't touch, without disabling the collider, and the problem went away. This suggests that the act of orphaning the GO immediately leads to the repositioning of the Parent based upon the colliders occupying the same space.

    However, in another experiment, I cached the Parent position prior to enabling/orphaning/repositioning (in that order) the GO, and then repositioning the Parent, and the physics engine still pushed it above the GO, even though it was far enough away the colliders were not overlapping any longer. It is clear the physics engine moved it after I reset its position back, after the colliders were apart.

    There is a bug and it seems that the physics engine acts on GO state that it caches perhaps when the GO is re-enabled. In any case, this is not intuitive at all and should not exhibit this behavior.
     
    Last edited: Jul 13, 2023
  5. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    453
    I will just point out that "I have no idea what is happening" and "I am convinced that it is a bug in the physics engine" don't seem to logically follow one another, if you catch my drift.

    You sound frustrated and it's easy to relate when stuff doesn't work. But you're likely just using it wrong. You say you "tweaked some parameters" then you "tweaked more parameters", and you make assumptions like "scale shouldn't affect physics" that are wrong. Of course scale affects physics cos it affects the center of mass.

    I don't know this accurately but sometimes you need to wait a frame. Such as, if you create a new collider on a gameobject, it will not work until next frame, at least with respect to triggering raycasts. And that's about when stuff happens under the hood. Unity has a lot of discussions around these.
     
    Last edited: Jul 13, 2023
  6. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    221
    As I described above it shouldn't happen. The colliders are not touching, but it treats them as they were. It isn't behaving as one would expect. You can say that it is a black box and thus it isn't a bug, and that I just don't know enough about it to understand why it's happening when it shouldn't.

    I'm done with this topic unless someone can explain why it should behave the way it does. To back up my conclusion, I can only present my observations and I did that.
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    Debug it. When two things collide you get a callback. Debug that.