Skip to content

Commit 2b92028

Browse files
fix: Nested NetworkTransform synchronization fails when parent has non-Vector3.one scale [MTT-6304] (#2538)
* fix This fixes an issue with interpolation causing nonauthoritative NetworkTransform instances to not properly reflect the final axis values when parenting changes. * test Updating the parenting test to validate the fix for parenting a nested NetworkTransform and assuring that values are the same. * fix Handle the condition that no new states have been pushed for a late joining client. (i.e. it just synchronized a nested NetworkTransform and that is it) * test Did an overhaul on the parented NetworkTransformTest (formerly NetworkTransformParentedLocalSpaceTest), renamed it to ParentedNetworkTransformTest, and now it tests both world and local space values depending upon how the NetworkObject is parented. * style removing commented out code. * update Adding entry to changelog * fix Migrating SetStateInternal into the Initialization method so it handles change of ownership.
1 parent cd50a00 commit 2b92028

File tree

3 files changed

+198
-64
lines changed

3 files changed

+198
-64
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1515
- Fixed issue where some temporary debug console logging was left in a merged PR. (#2562)
1616
- Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545)
1717
- Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events. (#2542,#2543)
18+
- 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)
1819
- Fixed issue where a server would include scene migrated and then despawned NetworkObjects to a client that was being synchronized. (#2532)
1920
- Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529)
2021
- 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)

com.unity.netcode.gameobjects/Components/NetworkTransform.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,16 +2392,6 @@ public override void OnNetworkSpawn()
23922392
m_CachedNetworkManager = NetworkManager;
23932393

23942394
Initialize();
2395-
// This assures the initial spawning of the object synchronizes all connected clients
2396-
// with the current transform values. This should not be placed within Initialize since
2397-
// that can be invoked when ownership changes.
2398-
if (CanCommitToTransform)
2399-
{
2400-
var currentPosition = GetSpaceRelativePosition();
2401-
var currentRotation = GetSpaceRelativeRotation();
2402-
// Teleport to current position
2403-
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
2404-
}
24052395
}
24062396

24072397
/// <inheritdoc/>
@@ -2472,6 +2462,7 @@ protected void Initialize()
24722462
CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner;
24732463
var replicatedState = ReplicatedNetworkState;
24742464
var currentPosition = GetSpaceRelativePosition();
2465+
var currentRotation = GetSpaceRelativeRotation();
24752466

24762467
if (CanCommitToTransform)
24772468
{
@@ -2483,6 +2474,9 @@ protected void Initialize()
24832474
// Authority only updates once per network tick
24842475
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;
24852476
NetworkManager.NetworkTickSystem.Tick += NetworkTickSystem_Tick;
2477+
2478+
// Teleport to current position
2479+
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
24862480
}
24872481
else
24882482
{
@@ -2494,15 +2488,42 @@ protected void Initialize()
24942488
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;
24952489

24962490
ResetInterpolatedStateToCurrentAuthoritativeState();
2497-
m_CurrentPosition = GetSpaceRelativePosition();
2491+
m_CurrentPosition = currentPosition;
24982492
m_CurrentScale = transform.localScale;
2499-
m_CurrentRotation = GetSpaceRelativeRotation();
2493+
m_CurrentRotation = currentRotation;
25002494

25012495
}
25022496

25032497
OnInitialize(ref replicatedState);
25042498
}
25052499

2500+
/// <inheritdoc/>
2501+
/// <remarks>
2502+
/// When a parent changes, non-authoritative instances should:
2503+
/// - Apply the resultant position, rotation, and scale from the parenting action.
2504+
/// - Clear interpolators (even if not enabled on this frame)
2505+
/// - Reset the interpolators to the position, rotation, and scale resultant values.
2506+
/// This prevents interpolation visual anomalies and issues during initial synchronization
2507+
/// </remarks>
2508+
public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject)
2509+
{
2510+
// Only if we are not authority
2511+
if (!CanCommitToTransform)
2512+
{
2513+
m_CurrentPosition = GetSpaceRelativePosition();
2514+
m_CurrentRotation = GetSpaceRelativeRotation();
2515+
m_CurrentScale = GetScale();
2516+
m_ScaleInterpolator.Clear();
2517+
m_PositionInterpolator.Clear();
2518+
m_RotationInterpolator.Clear();
2519+
var tempTime = new NetworkTime(NetworkManager.NetworkConfig.TickRate, NetworkManager.ServerTime.Tick).Time;
2520+
UpdatePositionInterpolator(m_CurrentPosition, tempTime, true);
2521+
m_ScaleInterpolator.ResetTo(m_CurrentScale, tempTime);
2522+
m_RotationInterpolator.ResetTo(m_CurrentRotation, tempTime);
2523+
}
2524+
base.OnNetworkObjectParentChanged(parentNetworkObject);
2525+
}
2526+
25062527
/// <summary>
25072528
/// Directly sets a state on the authoritative transform.
25082529
/// Owner clients can directly set the state on a server authoritative transform
@@ -2656,6 +2677,12 @@ protected virtual void Update()
26562677
}
26572678
}
26582679

2680+
// If we have not received any additional state updates since the very
2681+
// initial synchronization, then exit early.
2682+
if (m_LocalAuthoritativeNetworkState.IsSynchronizing)
2683+
{
2684+
return;
2685+
}
26592686
// Apply the current authoritative state
26602687
ApplyAuthoritativeState();
26612688
}

0 commit comments

Comments
 (0)