Search Unity

Question Collider on child GameObject not updated after parent transform change

Discussion in 'Physics' started by dyamanoha_, Nov 26, 2023.

  1. dyamanoha_

    dyamanoha_

    Joined:
    Mar 17, 2013
    Posts:
    87
    I'm doing a simple raycast against a collider that is in a nested heirarchy of game objects.

    The raycast works just fine until I apply a rotation to the root object in the heirarchy. It appears as though the colliders are still at their previous world transforms. The only way I can get the colliders to work correctly is to re-enable them either in the editor or script.

    Does anyone know why this might be happening?

    DETAIL: The children with colliders are instantiated prefabs that are parented into a GameObject hierarchy during scene load.

    UPDATE: It doesn't appear that this repros 100% of the time. It seems like there's some kind of race condition around collider updates. I think this might actually be related to being on a newer unity version 2023.2.0
     
    Last edited: Nov 26, 2023
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    Don't turn on AutoSyncTransforms, it's meant for backwards compatibility only and can become very expensive as it triggers a Physics.SyncTransform after every read operation in physics for properties that are related to positions/rotations etc.

    When you change a Transform, that's the only thing that changes. No other component will know about it, renderers will only see it when they render and physics will only see it when the simulation runs which is, by default, during the FixedUpdate.

    Physics is designed so you move a Rigidbody and the colliders are attached to it move along with it.

    Lots of devs though just ignore this and do what they want for the situation so they run into the out-of-sync issues because physics wants you to drive the physics components, it run the simulation then write to the Transforms and not the other way around where you write to the Transform whenever and it has to read from it when the simulation runs.

    If you want to modify the Transform (should be avoided) then you can manually call Physics.SyncTransforms to read all transform changes but you should also consider not working like that.
     
    zulo3d likes this.
  3. dyamanoha_

    dyamanoha_

    Joined:
    Mar 17, 2013
    Posts:
    87
    I don’t quite understand how this would result in collider internal state sometimes being updated and sometimes not. To be clear when this happens, it never gets synced back up until the enable flip regardless of physics ticks.

    But I understand what you’re saying.

    For those of us who are driving their own integration and just want to use colliders for manual geometry tests (don’t want a physics simulation but want a bounding volumes) what’s the best practice here?

    im kind of surprised that Collider.raycast doesn’t just concatenate the transform heirarchy and transform the ray into the collider space when called. Seems like the sane default behavior.
     
  4. dyamanoha_

    dyamanoha_

    Joined:
    Mar 17, 2013
    Posts:
    87
    I just thought of something while in the shower…

    This game is realtime with pause and pause is implemented by setting unity timescale to 0.

    Things can still rotate when paused though (telegraph a game action executed while paused)

    If it’s true that colliders stash their concatenated transforms on fixed update and fixed update ticks based on timescale then thats probably whats happening and why I thought it was non deterministic (I frequently pause the game without thinking about it). I’ll test once I get into the office
     
  5. dyamanoha_

    dyamanoha_

    Joined:
    Mar 17, 2013
    Posts:
    87
    Ok, that was 100% the problem. The FixedUpdate tick-rate must scale down with timeScale.

    I'm still curious what your thoughts are for those of us who just want colliders and manual geometry tests though.

    I guess I'm in a bit of a pickle now because I also use timeScale for slow-motion in the game and I really don't like the idea of colliders running behind other systems. Picking is the most obvious thing that might feel incorrect.

    Because Physics.SyncTransforms is a static function, I assume the entire scene hierarchy needs to be traversed and any dirty branches get stepped into?