You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When teleporting using CmdTeleport() characters can end up out of sync between client/server in a scenario where the player is moving while the server/host is loading a scene. What appears to happen is that in the time between the server trying to change the scene and the client receiving that message the player is still able to move, and that can cause a desync if the player is set to DDOL, and then gets CmdTeleport() called on it right after scene change.
Initially, I was also teleporting characters on character selection, and was seeing behavior similar to that which is described previously in #3588.
For the Start() behavior the character is moved to a location that is exactly double what it is supposed to be.
Version 89.8.0
Character is supposed to be teleporting to 1.00/1.00, and instead on Server side is shown at 2.00/2.00.
This happens when a CmdTeleport() is called in OnStartAuthority()
Once the character is desynced it remains throughout the session
Not always reproducible. Sometimes the teleport goes to the correct location. Other times it goes to the "doubled" location
For the OnSceneLoaded behavior the character can end up desynced based on how much they were able to move in the time that the server was loading the scene. This is always reproducible for me.
How can we reproduce the issue, step by step: For Start:
Calling the MoveToSpawnLocation() (below) within the OnStartAuthority() method sometimes caused the player to end up at "doubled" coordinates. (2, 2 instead of 1, 1)
For the desync when loading scenes:
Have a subscriber for the SceneManager.sceneLoaded trigger, that calls the MoveToSpawnLocation() (below) SceneManager.sceneLoaded += OnSceneLoaded;
Have a PlayerObjectController which is DDOL with DontDestroyOnLoad(this.gameObject);
With the code below in place on a PlayerObjectController, have a client move while the server loads a scene using ServerChangeScene(SceneName);
With the above steps this was always reproducible for me.
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded()
{
MoveToSpawnLocation()
}
public void MoveToSpawnLocation()
{
StartCoroutine(DelayedTeleport());
}
private IEnumerator DelayedTeleport()
{
while (!NetworkClient.ready)
{
inputManager.DisablePlayerInput();
yield return null;
}
if (isOwned)
{
// Removed initial code I use to find the spawnpoint to make repro easier
Vector3 pos = new Vector3(1, 1, 1);
Debug.Log($"Teleporting to: {pos}");
inputManager.EnablePlayerInput();
networkTransform.CmdTeleport(pos);
}
}
Expected behavior
When calling a CmdTeleport() after a scene change when a character was able to move there should not be a resulting desync between the location that the player teleports to, and the location that the player ends up at.
Screenshots
These pictures are from when these two characters were desynced with some debug text showing their location (client/server). This was a more mild case, but in extreme examples characters were able to get desynced up to 10+ units away.
Desktop (please complete the following information):
OS: Windows
Build target: Standalone
Unity version: 2022.3.43f1
Mirror branch: 89.8.0
Additional context
The previous bug #3588 had me looking in what I believe is the correct place, and I did actually workaround it for now. Commenting out all of the code in ResetState() except for base.ResetState() in NetworkReliableTransform fixed the issue and it was no longer reproducible.
The note at the top says the following. This, along with the previous bug is what prompted me to try commenting it out.
// reset state for next session.
// do not ever call this during a session (i.e. after teleport).
// calling this will break delta compression.
Indeed, once ResetState() in NetworkReliableTransform was only calling the base method I no longer saw the desync behavior on any scene changes when teleporting. I did not test whether this also resolved the desync when called from OnStartAuthority() because instead I simply Instantiated my player at the right location and stopped teleporting them.
For completeness, here is exactly what my ResetState() method looks like in NetworkReliableTransform, and I cannot reproduce it with this:
public override void ResetState()
{
base.ResetState();
// reset delta
//lastSerializedPosition = Vector3Long.zero;
//lastDeserializedPosition = Vector3Long.zero;
//lastSerializedScale = Vector3Long.zero;
//lastDeserializedScale = Vector3Long.zero;
// reset 'last' for delta too
//last = new TransformSnapshot(0, 0, Vector3.zero, Quaternion.identity, Vector3.zero);
}
The text was updated successfully, but these errors were encountered:
Describe the bug
When teleporting using
CmdTeleport()
characters can end up out of sync between client/server in a scenario where the player is moving while the server/host is loading a scene. What appears to happen is that in the time between the server trying to change the scene and the client receiving that message the player is still able to move, and that can cause a desync if the player is set to DDOL, and then getsCmdTeleport()
called on it right after scene change.Initially, I was also teleporting characters on character selection, and was seeing behavior similar to that which is described previously in #3588.
For the Start() behavior the character is moved to a location that is exactly double what it is supposed to be.
CmdTeleport()
is called inOnStartAuthority()
For the OnSceneLoaded behavior the character can end up desynced based on how much they were able to move in the time that the server was loading the scene. This is always reproducible for me.
How can we reproduce the issue, step by step:
For Start:
MoveToSpawnLocation()
(below) within theOnStartAuthority()
method sometimes caused the player to end up at "doubled" coordinates. (2, 2 instead of 1, 1)For the desync when loading scenes:
MoveToSpawnLocation()
(below)SceneManager.sceneLoaded += OnSceneLoaded;
DontDestroyOnLoad(this.gameObject);
ServerChangeScene(SceneName);
Expected behavior
When calling a
CmdTeleport()
after a scene change when a character was able to move there should not be a resulting desync between the location that the player teleports to, and the location that the player ends up at.Screenshots
These pictures are from when these two characters were desynced with some debug text showing their location (client/server). This was a more mild case, but in extreme examples characters were able to get desynced up to 10+ units away.
Desktop (please complete the following information):
Additional context
The previous bug #3588 had me looking in what I believe is the correct place, and I did actually workaround it for now. Commenting out all of the code in
ResetState()
except forbase.ResetState()
in NetworkReliableTransform fixed the issue and it was no longer reproducible.The note at the top says the following. This, along with the previous bug is what prompted me to try commenting it out.
Indeed, once
ResetState()
in NetworkReliableTransform was only calling the base method I no longer saw the desync behavior on any scene changes when teleporting. I did not test whether this also resolved the desync when called fromOnStartAuthority()
because instead I simply Instantiated my player at the right location and stopped teleporting them.For completeness, here is exactly what my
ResetState()
method looks like in NetworkReliableTransform, and I cannot reproduce it with this:The text was updated successfully, but these errors were encountered: