Auto Sync Transforms and moving objects

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?

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.

[quote=“SVC_Games”, post:1, topic: 744465]
(or should I say, raycasts) seems to have problems… Is there any workaround?
[/quote]
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.

[quote=“SVC_Games”, post:1, topic: 744465]
Is AutoSync Transforms such a huge performance hit?
[/quote]
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.

[quote=“SVC_Games”, post:1, topic: 744465]
Will it be removed in the future?
[/quote]
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).

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?

[quote=“SVC_Games”, post:3, topic: 744465]
Also I’m curious, the performance lost created by using “Autosync”
[/quote]
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.

1 Like

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.

[quote=“SVC_Games”, post:5, topic: 744465]
sorry for the misunderstanding
[/quote]
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.

2 Likes

[quote=“MelvMay”, post:6, topic: 744465]
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.
[/quote]
Thanks for the in-depth response, that pretty much covers all my questions. Great information to think about :slight_smile:

Melv, I've seen you post on this before, but in Unity's own basic tutorial for 2D Physics it describes moving a platform with a kinematic Rigidbody2D by its transform. Additionally I have seen posts by other Unity staff that said for a KINEMATIC (not dynamic) Rigidbody2D moving the transform is fine ( https://discussions.unity.com/t/673683 ).

What I have found is that moving a Rigidbody2D in FixedUpdate (my understanding is that this is the proper place for anything physics-related) even with interpolate doesn't move as smoothly as just moving its transform in Update, and the loss of smooth motion outweighs the loss in collision detection, at least in our application. I have seen this behavior confirmed in a few posts as well. Regardless, it seems like auto sync transforms allows you the best of both worlds with some minor performance sacrifice--the post I linked above "0.1-0.5 ms" for "large setups." What are your thoughts?

Separately, I wish the documentation and tutorials were more clear on this: if we shouldn't be moving a kinematic rigidbody2d by its transform then it shouldn't discuss that very thing in the Physics2D tutorial.

2 Likes

Nobody said it won't work. What has been asked and described is what can give you better performance and how and why it has been done.

I didn't write those tutorials, a lot of them were done by the learn team well before the Transform system was changed and you're also referring to a member of staff discussing in 2017 discussing the 3D physics system whereas I'm telling you about the 2D physics system. I've also done my absolute best to go over this many times but now you want more detail somewhere.

Finally, tutorials are not 100% efficient; they're there to give you general overviews of stuff and not to give you a line-by-line guarantee that this is how you should do it.

1 Like

[quote=“unity_BUIockkbCwDQ9w”, post:8, topic: 744465]
What I have found is that moving a Rigidbody2D in FixedUpdate (my understanding is that this is the proper place for anything physics-related) even with interpolate doesn’t move as smoothly as just moving its transform in Update, and the loss of smooth motion outweighs the loss in collision detection, at least in our application. I have seen this behavior confirmed in a few posts as well.
[/quote]
This just isn’t true but who am I to argue if someone else said it on the forums. :wink:

[quote=“unity_BUIockkbCwDQ9w”, post:8, topic: 744465]
Regardless, it seems like auto sync transforms allows you the best of both worlds with some minor performance sacrifice–the post I linked above “0.1-0.5 ms” for “large setups.” What are your thoughts?
[/quote]
I really have no idea what you’re talking about here. AutoSyncTransforms has nothing whatsoever to do with MovePosition, when you call it etc etc etc. Really, this is just blending ideas and concepts and getting things confused.

It really does sound like you don’t follow what it does. Maybe you do but your questions would suggest that and so I’m sorry if that’s not the case.

By far the biggest problem in Unity is that it ALLOWS you do things several ways. On top of that, devs make conflicting script calls all the time; many of my weekly posts on the forums are about this confusion. This is why I make a single, simple statement: Do NOT modify Tranforms when using 2D physics components; use the Rigidbody2D API because (if you didn’t realise it) you’re adding that to tell it that it’s in charge of the Transform!! Physics queries do not care about the Transform system so why would you go through the Transform system so that at some point the physics system has to read it, then modify the physics components so that you can then perform your query.

Really, no amount of “docs” will stop this confusion. The problem is that we cannot stop devs making conflicting calls and creating confusion over when things should be done because other devs invent stuff which is then read by other devs and taken as true. I’ve tried my best over the years to correct this but it’s impossible.

2 Likes