Search Unity

Auto Sync Transforms and moving objects

Discussion in 'Physics' started by SVC-Games, May 23, 2019.

  1. SVC-Games

    SVC-Games

    Joined:
    May 21, 2013
    Posts:
    112
    I'm making a 2D character controller using raycast to detect platforms, etc. And so far so good. Jumps, collisions are ok, moving a Rigidbody2D using MovePosition in FixedUpdate...

    The problem comes when interacting with platforms. The platforms are made in a similar way to this:


    If I enable "Auto Sync Transforms" it works flawesly. If it's disabled, when moving down it seems that the player is "1 frame behind", not really "contacting" with the platform. Worst yet, if I fall onto a platform when the platform is going up, the player falls through it sometimes.

    I've tried Smart Platform Colliders from the asset store and it have the same problem! https://assetstore.unity.com/packages/templates/systems/smart-platform-colliders-47229

    When AutoSync is enabled, everything works perfectly. But with it disabled some collisions (or should I say, raycasts) seems to have problems... Is there any workaround?

    Is AutoSync Transforms such a huge performance hit? Will it be removed in the future?
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    2,168
    AutoSyncTransforms simply controls when a transform-change (made by you) updates the physics bodies so they stay in sync with those changes. It doesn't affect the physics systems ability to detect collisions but with it off, physics objects won't be at the new transform position (you set) until the next sim step. A common error is using queries (raycasts etc) based upon transform poses when it should be off the rigidbody poses. For instance, when using interpolation the transform isn't going to be the same as the current body position/rotation.

    Yes, stop moving physics stuff via transforms. You shouldn't however be moving things via transforms anyway so this should never be a problem. Always perform actions directly on physics objects.

    If it's on, for backwards compatibility, it has to check if you've made any transform changes since the last time it checked so it depends on your project but no work is better and it should be off, which it is by default on new projects.

    Why would we remove it? It's not a physics "feature", it's a backwards compatibility option only due to the transform changes in the core engine a fair while ago (transforms now don't perform change callbacks so they are compatible with the job-system).
     
  3. SVC-Games

    SVC-Games

    Joined:
    May 21, 2013
    Posts:
    112
    In fact I've just double checked and the platform was moving using translate instead of movePosition (my mistake). But still no dice for a convincing platform :/

    Just to be clear:

    - Player is using a box collider with KINEMATIC rigidbody. Raycasts are used in FixedUpdate to check for ground/ceilings/walls/slopes to determine a velocity that is finally applied to the rigidbody using MovePosition.

    - The platform (also a kinematic rigidbody) is also moved using MovePosition in fixed update. It also checks if there's a "passenger" (raycasting looking for "players"). If so, it applies it's velocity to the passenger but...
    • When moving down, the player is "slightly" behind the platform (It's "falling behind" trying to land)
    • When moving upwards the player just go though the platform.
    • If the platform is moving sideways the player stays still in the world (not being transported along)
    I'm working on it :p. Maybe a more useful solution is doing it the other way around: The player checks if it's on a moving platform and if so adopts it's velocity, instead of the platform altering the player's velocity.

    Also I'm curious, the performance lost created by using "Autosync" I assume only affects altering transforms of gameobjects with rigidbody (kinematic), colliders or both. Altering transforms of game objects without those components should't be affected since they have no physics elements?
     
    Last edited: May 24, 2019
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    2,168
    What performance loss? If you don't make any modifications to transforms then it has very little work to do. Note that the code that checks this isn't in the physics system, it's the Transform system. All the physics system does is "register" which GO it's interested in knowing about changes for. This is done for all GO with either a Rigidbody or Collider. We then ask, prior to running the simulation, if any transforms have changed because that's an instruction from the user to directly change the pose (should be avoided).

    Any work done on a Rigidbody or Collider is the same no matter whether it's done all in one go or done immediately (how it used to work). AutoSyncTransform doesn't change that work. What does change however is (if AutoSyncTransform is on) that we have to check for any transform changes prior to any query. This is why it being off is default.

    Other systems will do the same if they're interested in knowing if a transform has changed. Most other systems related to rendering don't bother AFAIK because they just read the transform when they need it. Physics, specifically a Rigidbody, however has its own pose so when you change the Transform directly it has to update the body. This is why we say don't do that and drive the transform instead.

    I'll say again though because it is important, this has no impact on the simulation at all. All it can do is change when you change a RB/Collider by manipulating a transform; something you shouldn't do. If you're seeing a difference then you're changing a Transform somewhere, whether implicitly or via some animation perhaps.
     
  5. SVC-Games

    SVC-Games

    Joined:
    May 21, 2013
    Posts:
    112
    I'm not saying there's an actual performance loss. From what I've read about autosync it seemed to me that having it turned off would be a performance gain since it's "avoiding an extra step" and turning it off could result in worse performance if there's "rogue" physics-based gameobject incorrectly altered by their transform, sorry for the misunderstanding.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    2,168
    No need for an apology. it's not immediately clear on what it's doing for sure. I'll write-up what it's doing here, even though I've described some of it above; hopefully it'll help.

    In the end, a team within Unity change Transforms so that they don't perform callbacks so systems like physics have no idea if a user changes a Transform. This obviously caused a serious problem for physics as we used this to update the rigidbody pose if it happened before returning to the user. If you changed a transform position then changed a transform rotation separately then you'd get two updates. Indeed, this kind of stuff happened all the time and could be a real performance hog for user projects.

    The only way both 2D/3D physics systems could continue to have backwards compatibility was to ensure that any changed transforms updated the rigidbody poses when it matters. It only matters when something wants to read any physics state related to rigidbodies so queries or the body pose. This meant we had to sync-transforms but always doing this each time a query (etc) was run would be silly so we only do this when AutoSyncTransforms is on and this option is off by default for new projects.

    Now we always sync-transforms prior to the physics simulation running so if that option is off, it's done once only per simulation step. Sync-transforms isn't a physics thing, it's a transform thing we call and it tells us if any transforms have changed for GameObjects that have either a Rigidbody or Collider on it. The transform system itself (AFAIK) has a fast-track that if no transforms are change for these GO then it returns very quickly. I'm not sure the difference between no transform changed and a single one but the time is within the transform system, not physics.

    What we get from the transform system is a bunch of GameObjects. We can then perform the action on the RB/Collider for that GameObject; something we would've done synchronous to the original transform change previously. Now we do them in one go. This also means that if you change a Transform 10 times, we only perform a single Rigidbody/Collider update so there's a potential perf gain there (even if you do separate position/rotation/scale changes).

    So in summary:
    With AutoSyncTransforms off, we automatically perform a transform system once per simulation step. This ensures we have any changes the user makes to transforms. Hopefully there are none and the transform system can uses its early-out-because-no-changes code. This means however that if you change a Transform, the Rigidbody/Collider on it are not updated to that state. If you query it then you'll be querying the last state or since the last time SyncTransforms was called.

    With AutoSynTransforms on, we still automatically perform a transform system once per simulation step but we also perform it upon any query or read operation that can read results that can be changed via a transform change. This obviously has overhead but again, if there are none then it should be very quick returning from the transform system. This also means that when you change a transform, the rigidbody/collider are immediately updated so querying gives you the results based upon that change. It also means multiple transform changes means multiple rigidbody/collider changes.

    Hope that helps.
     
  7. SVC-Games

    SVC-Games

    Joined:
    May 21, 2013
    Posts:
    112
    Thanks for the in-depth response, that pretty much covers all my questions. Great information to think about :)
     
unityunity