- Home /
Overriding object Transform every frame for multi-coordinate system stops Unity physics
I have a very complex simulation in a large scale spherical terrain environment that has been developed in Monogame. We are in the process of evaluating Unity for integration with it. Consider it an enormous black box that uses its own coordinate system - you provide game objects to it as input, it transforms their positions and returns them for rendering.
What we need is the ability to intercept and override the Transform of every gameobject that is used by our system, but only for rendering - keep its Transform exactly the same, in Unity 0,0,0-based coordinate space for updates, physics, that sort of thing, and before it is used for rendering, replace it with the transformed Transform generated by our system. Then, seamlessly put it back into Unity space for physics and such to continue as normal. This allows us to utilize two coordinate spaces at once, which is a critical feature.
With the assistance of the unity channel on a large game dev discord, I've been able to prototype almost all of the way there. Currently, I have a script attached to every gameobject that does this:
bool haveTransform = false;
Vector3 tmpPosition = Vector3.zero;
Quaternion tmpRotation = Quaternion.identity;
Vector3 tmpScale = Vector3.zero;
private void OnEnable()
{
FirstScript.PreUpdate += HandlePreUpdate;
}
void HandlePreUpdate()
{
if (haveTransform)
{
this.transform.position = tmpPosition;
this.transform.rotation = tmpRotation;
this.transform.localScale = tmpScale;
}
}
private void LateUpdate()
{
tmpPosition = this.transform.position;
tmpRotation = this.transform.rotation;
tmpScale = this.transform.localScale;
haveTransform = true;
this.transform.position = ComputeRenderedTransformPosition();
...
}
I followed the steps in this question https://answers.unity.com/questions/614343/how-to-implement-preupdate-function.html to implement the PreUpdate method - I also attached the FirstScript to an object in the scene so that the event would be fired in game.
And, this works great! Objects are properly translated into our coordinate system for rendering, woohoo! :D
The issue arises when attempting to support Unity's physics. If I set up a test scene with a few cubes on top of a quad, and do not enable that script, thus leaving them completely in Unity's coordinate space, then it naturally works as expected - the cubes tumble playfully to the ground with lovely physics and all that. However, once I enable the script, they simply freeze in space - no physics are applied, nothing.
I am assuming that the issue is that the physics engine detects that the Transform was modified that frame, assumes that it was repositioned, and skips updating their physics that frame. Since this is not the case, I need to find a way to suppress this behavior.
Someone on the Discord suggested that I try calling Physics.SyncTransforms() each frame - I tried doing so in a few different places, but it doesn't seem to have any effect. Any further help would be greatly appreciated!
Your answer
![](https://koobas.hobune.stream/wayback/20220612175338im_/https://answers.unity.com/themes/thub/images/avi.jpg)