Skip to content

Commit fdebb55

Browse files
fix: Set state private RPC handlers were not honoring local vs world space assignment of position and rotation (#2203)
* fix SetStateClientRpc and SetStateServerRpc were not updated to use SetStateInternal which honors local vs world space transform setting.s * update changelog * test Modified existing tests to include testing SetState which validates the changes made to NetworkTransform.SetState and associated private methods. * update adding the PR number to the changelog entry. * test removing conditional check that was not needed. * update adding further clarity as to where the two rpc methods were located.
1 parent 43218a3 commit fdebb55

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1919

2020
### Fixed
2121

22+
- Fixed issue where `NetworkTransform.SetStateServerRpc` and `NetworkTransform.SetStateClientRpc` were not honoring local vs world space settings when applying the position and rotation. (#2203)
2223
- Fixed ILPP `TypeLoadException` on WebGL on MacOS Editor and potentially other platforms. (#2199)
2324
- Implicit conversion of NetworkObjectReference to GameObject will now return null instead of throwing an exception if the referenced object could not be found (i.e., was already despawned) (#2158)
2425
- Fixed warning resulting from a stray NetworkAnimator.meta file (#2153)

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

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,11 +1169,7 @@ private void SetStateInternal(Vector3 pos, Quaternion rot, Vector3 scale, bool s
11691169
private void SetStateClientRpc(Vector3 pos, Quaternion rot, Vector3 scale, bool shouldTeleport, ClientRpcParams clientRpcParams = default)
11701170
{
11711171
// Server dictated state is always applied
1172-
transform.position = pos;
1173-
transform.rotation = rot;
1174-
transform.localScale = scale;
1175-
m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = shouldTeleport;
1176-
TryCommitTransform(transform, m_CachedNetworkManager.LocalTime.Time);
1172+
SetStateInternal(pos, rot, scale, shouldTeleport);
11771173
}
11781174

11791175
/// <summary>
@@ -1190,12 +1186,7 @@ private void SetStateServerRpc(Vector3 pos, Quaternion rot, Vector3 scale, bool
11901186
{
11911187
(pos, rot, scale) = OnClientRequestChange(pos, rot, scale);
11921188
}
1193-
1194-
transform.position = pos;
1195-
transform.rotation = rot;
1196-
transform.localScale = scale;
1197-
m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = shouldTeleport;
1198-
TryCommitTransform(transform, m_CachedNetworkManager.LocalTime.Time);
1189+
SetStateInternal(pos, rot, scale, shouldTeleport);
11991190
}
12001191

12011192
/// <summary>

com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ public enum TransformSpace
189189
public enum OverrideState
190190
{
191191
Update,
192-
CommitToTransform
192+
CommitToTransform,
193+
SetState
193194
}
194195

195196
/// <summary>
@@ -299,9 +300,8 @@ private IEnumerator WaitForAllChildrenLocalTransformValuesToMatch()
299300
/// parented under another NetworkTransform
300301
/// </summary>
301302
[UnityTest]
302-
public IEnumerator NetworkTransformParentedLocalSpaceTest([Values] Interpolation interpolation, [Values] OverrideState overideState)
303+
public IEnumerator NetworkTransformParentedLocalSpaceTest([Values] Interpolation interpolation)
303304
{
304-
var overrideUpdate = overideState == OverrideState.CommitToTransform;
305305
m_AuthoritativeTransform.Interpolate = interpolation == Interpolation.EnableInterpolate;
306306
m_NonAuthoritativeTransform.Interpolate = interpolation == Interpolation.EnableInterpolate;
307307
var authoritativeChildObject = SpawnObject(m_ChildObjectToBeParented.gameObject, m_AuthoritativeTransform.NetworkManager);
@@ -334,15 +334,28 @@ public IEnumerator NetworkTransformParentedLocalSpaceTest([Values] Interpolation
334334
/// Validates that moving, rotating, and scaling the authority side with a single
335335
/// tick will properly synchronize the non-authoritative side with the same values.
336336
/// </summary>
337-
private IEnumerator MoveRotateAndScaleAuthority(Vector3 position, Vector3 rotation, Vector3 scale)
337+
private IEnumerator MoveRotateAndScaleAuthority(Vector3 position, Vector3 rotation, Vector3 scale, OverrideState overrideState)
338338
{
339-
m_AuthoritativeTransform.transform.position = position;
340-
yield return null;
341-
var authoritativeRotation = m_AuthoritativeTransform.transform.rotation;
342-
authoritativeRotation.eulerAngles = rotation;
343-
m_AuthoritativeTransform.transform.rotation = authoritativeRotation;
344-
yield return null;
345-
m_AuthoritativeTransform.transform.localScale = scale;
339+
switch (overrideState)
340+
{
341+
case OverrideState.SetState:
342+
{
343+
m_AuthoritativeTransform.SetState(position, Quaternion.Euler(rotation), scale);
344+
break;
345+
}
346+
case OverrideState.Update:
347+
default:
348+
{
349+
m_AuthoritativeTransform.transform.position = position;
350+
yield return null;
351+
var authoritativeRotation = m_AuthoritativeTransform.transform.rotation;
352+
authoritativeRotation.eulerAngles = rotation;
353+
m_AuthoritativeTransform.transform.rotation = authoritativeRotation;
354+
yield return null;
355+
m_AuthoritativeTransform.transform.localScale = scale;
356+
break;
357+
}
358+
}
346359
}
347360

348361
/// <summary>
@@ -400,7 +413,6 @@ protected override void OnNewClientCreated(NetworkManager networkManager)
400413
[UnityTest]
401414
public IEnumerator NetworkTransformMultipleChangesOverTime([Values] TransformSpace testLocalTransform, [Values] OverrideState overideState)
402415
{
403-
var overrideUpdate = overideState == OverrideState.CommitToTransform;
404416
m_AuthoritativeTransform.InLocalSpace = testLocalTransform == TransformSpace.Local;
405417

406418
var positionStart = new Vector3(1.0f, 0.5f, 2.0f);
@@ -422,7 +434,7 @@ public IEnumerator NetworkTransformMultipleChangesOverTime([Values] TransformSpa
422434
yield return WaitForNextTick();
423435

424436
// Apply deltas
425-
MoveRotateAndScaleAuthority(position, rotation, scale);
437+
MoveRotateAndScaleAuthority(position, rotation, scale, overideState);
426438

427439
// Wait for deltas to synchronize on non-authoritative side
428440
yield return WaitForPositionRotationAndScaleToMatch(4);
@@ -455,7 +467,7 @@ public IEnumerator NetworkTransformMultipleChangesOverTime([Values] TransformSpa
455467
// to apply both deltas within the same tick period.
456468
yield return WaitForNextTick();
457469

458-
MoveRotateAndScaleAuthority(position, rotation, scale);
470+
MoveRotateAndScaleAuthority(position, rotation, scale, overideState);
459471
yield return WaitForPositionRotationAndScaleToMatch(4);
460472
}
461473

@@ -471,7 +483,7 @@ public IEnumerator NetworkTransformMultipleChangesOverTime([Values] TransformSpa
471483
rotation = rotationStart * i;
472484
scale = scaleStart * i;
473485

474-
MoveRotateAndScaleAuthority(position, rotation, scale);
486+
MoveRotateAndScaleAuthority(position, rotation, scale, overideState);
475487
}
476488

477489
yield return WaitForPositionRotationAndScaleToMatch(1);
@@ -486,7 +498,7 @@ public IEnumerator NetworkTransformMultipleChangesOverTime([Values] TransformSpa
486498
position = positionStart * i;
487499
rotation = rotationStart * i;
488500
scale = scaleStart * i;
489-
MoveRotateAndScaleAuthority(position, rotation, scale);
501+
MoveRotateAndScaleAuthority(position, rotation, scale, overideState);
490502
}
491503
yield return WaitForPositionRotationAndScaleToMatch(1);
492504
}
@@ -513,32 +525,47 @@ public IEnumerator TestAuthoritativeTransformChangeOneAtATime([Values] Transform
513525

514526
Assert.AreEqual(Vector3.zero, m_NonAuthoritativeTransform.transform.position, "server side pos should be zero at first"); // sanity check
515527

516-
authPlayerTransform.position = new Vector3(10, 20, 30);
517-
if (overrideUpdate)
528+
var nextPosition = new Vector3(10, 20, 30);
529+
if (overideState != OverrideState.SetState)
518530
{
531+
authPlayerTransform.position = nextPosition;
519532
m_OwnerTransform.CommitToTransform();
520533
}
534+
else
535+
{
536+
m_OwnerTransform.SetState(nextPosition, null, null, m_AuthoritativeTransform.Interpolate);
537+
}
521538

522539
yield return WaitForConditionOrTimeOut(PositionsMatch);
523540
AssertOnTimeout($"Timed out waiting for positions to match");
524541

525542
// test rotation
526543
Assert.AreEqual(Quaternion.identity, m_NonAuthoritativeTransform.transform.rotation, "wrong initial value for rotation"); // sanity check
527544

528-
authPlayerTransform.rotation = Quaternion.Euler(45, 40, 35); // using euler angles instead of quaternions directly to really see issues users might encounter
529-
if (overrideUpdate)
545+
var nextRotation = Quaternion.Euler(45, 40, 35); // using euler angles instead of quaternions directly to really see issues users might encounter
546+
if (overideState != OverrideState.SetState)
530547
{
548+
authPlayerTransform.rotation = nextRotation;
531549
m_OwnerTransform.CommitToTransform();
532550
}
551+
else
552+
{
553+
m_OwnerTransform.SetState(null, nextRotation, null, m_AuthoritativeTransform.Interpolate);
554+
}
533555

534556
yield return WaitForConditionOrTimeOut(RotationsMatch);
535557
AssertOnTimeout($"Timed out waiting for rotations to match");
536558

537-
authPlayerTransform.localScale = new Vector3(2, 3, 4);
559+
var nextScale = new Vector3(2, 3, 4);
538560
if (overrideUpdate)
539561
{
562+
authPlayerTransform.localScale = nextScale;
540563
m_OwnerTransform.CommitToTransform();
541564
}
565+
else
566+
{
567+
m_OwnerTransform.SetState(null, null, nextScale, m_AuthoritativeTransform.Interpolate);
568+
}
542569

543570
yield return WaitForConditionOrTimeOut(ScaleValuesMatch);
544571
AssertOnTimeout($"Timed out waiting for scale values to match");

0 commit comments

Comments
 (0)