Skip to content

fix: Nested NetworkTransform synchronization fails when parent has non-Vector3.one scale [MTT-6304] #2538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Fixed issue where some temporary debug console logging was left in a merged PR. (#2562)
- Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545)
- Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events. (#2542,#2543)
- Fixed issue where parenting a NetworkTransform under a transform with a scale other than Vector3.one would result in incorrect values on non-authoritative instances. (#2538)
- Fixed issue where a server would include scene migrated and then despawned NetworkObjects to a client that was being synchronized. (#2532)
- Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529)
- Making a `NetworkVariable` with an `INetworkSerializable` type that doesn't meet the `new()` constraint will now create a compile-time error instead of an editor crash (#2528)
Expand Down
51 changes: 39 additions & 12 deletions com.unity.netcode.gameobjects/Components/NetworkTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2392,16 +2392,6 @@ public override void OnNetworkSpawn()
m_CachedNetworkManager = NetworkManager;

Initialize();
// This assures the initial spawning of the object synchronizes all connected clients
// with the current transform values. This should not be placed within Initialize since
// that can be invoked when ownership changes.
if (CanCommitToTransform)
{
var currentPosition = GetSpaceRelativePosition();
var currentRotation = GetSpaceRelativeRotation();
// Teleport to current position
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
}
}

/// <inheritdoc/>
Expand Down Expand Up @@ -2472,6 +2462,7 @@ protected void Initialize()
CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner;
var replicatedState = ReplicatedNetworkState;
var currentPosition = GetSpaceRelativePosition();
var currentRotation = GetSpaceRelativeRotation();

if (CanCommitToTransform)
{
Expand All @@ -2483,6 +2474,9 @@ protected void Initialize()
// Authority only updates once per network tick
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;
NetworkManager.NetworkTickSystem.Tick += NetworkTickSystem_Tick;

// Teleport to current position
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
}
else
{
Expand All @@ -2494,15 +2488,42 @@ protected void Initialize()
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;

ResetInterpolatedStateToCurrentAuthoritativeState();
m_CurrentPosition = GetSpaceRelativePosition();
m_CurrentPosition = currentPosition;
m_CurrentScale = transform.localScale;
m_CurrentRotation = GetSpaceRelativeRotation();
m_CurrentRotation = currentRotation;

}

OnInitialize(ref replicatedState);
}

/// <inheritdoc/>
/// <remarks>
/// When a parent changes, non-authoritative instances should:
/// - Apply the resultant position, rotation, and scale from the parenting action.
/// - Clear interpolators (even if not enabled on this frame)
/// - Reset the interpolators to the position, rotation, and scale resultant values.
/// This prevents interpolation visual anomalies and issues during initial synchronization
/// </remarks>
public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject)
{
// Only if we are not authority
if (!CanCommitToTransform)
{
m_CurrentPosition = GetSpaceRelativePosition();
m_CurrentRotation = GetSpaceRelativeRotation();
m_CurrentScale = GetScale();
m_ScaleInterpolator.Clear();
m_PositionInterpolator.Clear();
m_RotationInterpolator.Clear();
var tempTime = new NetworkTime(NetworkManager.NetworkConfig.TickRate, NetworkManager.ServerTime.Tick).Time;
UpdatePositionInterpolator(m_CurrentPosition, tempTime, true);
m_ScaleInterpolator.ResetTo(m_CurrentScale, tempTime);
m_RotationInterpolator.ResetTo(m_CurrentRotation, tempTime);
}
base.OnNetworkObjectParentChanged(parentNetworkObject);
}

/// <summary>
/// Directly sets a state on the authoritative transform.
/// Owner clients can directly set the state on a server authoritative transform
Expand Down Expand Up @@ -2656,6 +2677,12 @@ protected virtual void Update()
}
}

// If we have not received any additional state updates since the very
// initial synchronization, then exit early.
if (m_LocalAuthoritativeNetworkState.IsSynchronizing)
{
return;
}
// Apply the current authoritative state
ApplyAuthoritativeState();
}
Expand Down
Loading