Skip to content

Commit dea7aae

Browse files
fix
Fix issue where client owner authority NetworkTransform would not set the right IsParented status when sending a parenting directive.
1 parent 79b602a commit dea7aae

File tree

1 file changed

+43
-21
lines changed

1 file changed

+43
-21
lines changed

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

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,8 @@ internal bool SynchronizeScale
14771477
/// This field doesn't auto-synchronize with non-authority clients if changed on the authority instance during runtime (so you should apply this setting in-Editor).
14781478
/// Read the NetworkTransform documentation for more information and to avoid improper use.
14791479
/// </remarks>
1480+
[Tooltip("When enabled, NetworkTransform controls world or local space settings while also providing smooth parenting transitions." +
1481+
"When disabled, world or local space settings have to be adjusted by script or in the inspector view.")]
14801482
public bool SwitchTransformSpaceWhenParented = false;
14811483

14821484
/// <summary>
@@ -2128,7 +2130,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, ref Tra
21282130
networkState.IsSynchronizing = isSynchronization;
21292131

21302132
// Check for parenting when synchronizing and/or teleporting
2131-
if (isSynchronization || networkState.IsTeleportingNextFrame)
2133+
if (isSynchronization || networkState.IsTeleportingNextFrame || forceState)
21322134
{
21332135
// This all has to do with complex nested hierarchies and how it impacts scale
21342136
// when set for the first time or teleporting and depends upon whether the
@@ -3495,6 +3497,12 @@ protected virtual void Awake()
34953497
m_RotationInterpolator = new BufferedLinearInterpolatorQuaternion();
34963498
m_PositionInterpolator = new BufferedLinearInterpolatorVector3();
34973499
m_ScaleInterpolator = new BufferedLinearInterpolatorVector3();
3500+
3501+
// Always start in world space until spawned and initialized.
3502+
if (SwitchTransformSpaceWhenParented)
3503+
{
3504+
InLocalSpace = false;
3505+
}
34983506
}
34993507

35003508
/// <inheritdoc/>
@@ -4446,9 +4454,10 @@ internal void TransformStateUpdate(ulong senderId, bool isParentingDirective)
44464454
/// </summary>
44474455
internal void ParentingUpdate(NetworkObject parent, bool worldPositionStays)
44484456
{
4457+
InLocalSpace = parent;
44494458
// Super-edge case when spawning an object with ownership and then immeidatley
44504459
// parenting. If so, update the current position and rotation values.
4451-
if (!CanCommitToTransform && IsServer)
4460+
if (!CanCommitToTransform && IsServer && InLocalSpace)
44524461
{
44534462
m_InternalCurrentPosition = transform.localPosition;
44544463
m_InternalCurrentRotation = transform.localRotation;
@@ -4457,39 +4466,36 @@ internal void ParentingUpdate(NetworkObject parent, bool worldPositionStays)
44574466
m_HalfPositionState.UpdateFrom(ref m_InternalCurrentPosition, m_CachedNetworkManager.LocalTime.Tick);
44584467
}
44594468
}
4460-
InLocalSpace = parent;
44614469
m_OutboundMessage.SetParent(new NetworkObjectReference(parent), worldPositionStays);
44624470

44634471
var transformToCommit = transform;
44644472
CheckForStateChange(ref m_LocalAuthoritativeNetworkState, ref transformToCommit, false, forceState: true);
44654473
UpdateTransformState();
44664474
// Reset the parent state for next state update that might not have a parent directive included
44674475
m_OutboundMessage.ResetParent();
4476+
m_PreviousParent = parent;
44684477
}
44694478

44704479
private NetworkObject m_PreviousParent;
44714480

44724481
internal void UpdateParenting(NetworkObjectReference parent, bool worldPositionStays)
44734482
{
44744483
var parentObject = (NetworkObject)null;
4475-
var removeParent = !parent.TryGet(out parentObject);
4484+
var isParenting = parent.TryGet(out parentObject);
4485+
4486+
if (m_PreviousParent && InboundState.IsParented != isParenting)
4487+
{
4488+
Debug.LogError($"[Client-{NetworkManager.LocalClientId}][{name}][Parenting Directive Mismatch] Inbound state " +
4489+
$"{nameof(NetworkTransformState.IsParented)} is {InboundState.IsParented} and isParenting is {isParenting}!");
4490+
}
4491+
44764492
// Parent
44774493
NetworkObject.AuthorityAppliedParenting = true;
44784494
ulong? parentObjectId = parentObject ? parentObject.NetworkObjectId : null;
44794495
NetworkObject.SetNetworkParenting(parentObjectId, worldPositionStays);
4480-
NetworkObject.ApplyNetworkParenting(removeParent: removeParent);
4481-
if (!removeParent)
4496+
NetworkObject.ApplyNetworkParenting(removeParent: !isParenting);
4497+
if (isParenting)
44824498
{
4483-
// Convert the world space transform values to the local space of the new transform
4484-
if (SynchronizePosition)
4485-
{
4486-
m_InternalCurrentPosition = parentObject.transform.InverseTransformPoint(transform.position);
4487-
}
4488-
if (SynchronizeRotation)
4489-
{
4490-
m_InternalCurrentRotation = Quaternion.Inverse(parentObject.transform.rotation) * m_InternalCurrentRotation;
4491-
}
4492-
44934499
// If we had a previous parent...
44944500
if (m_PreviousParent && InLocalSpace)
44954501
{
@@ -4505,8 +4511,21 @@ internal void UpdateParenting(NetworkObjectReference parent, bool worldPositionS
45054511
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
45064512
}
45074513
}
4508-
InLocalSpace = true;
4509-
// Convert the world space values of the interpolators to local space
4514+
else if (m_PreviousParent && !InLocalSpace)
4515+
{
4516+
Debug.LogError($"[Client-{NetworkManager.LocalClientId}][{name}][Parenting Directive Mismatch] {nameof(m_PreviousParent)} is not null but {nameof(InLocalSpace)} is {InLocalSpace}!");
4517+
}
4518+
4519+
// Convert the world space transform values to the local space of the new transform
4520+
if (SynchronizePosition)
4521+
{
4522+
m_InternalCurrentPosition = parentObject.transform.InverseTransformPoint(transform.position);
4523+
}
4524+
if (SynchronizeRotation)
4525+
{
4526+
m_InternalCurrentRotation = Quaternion.Inverse(parentObject.transform.rotation) * m_InternalCurrentRotation;
4527+
}
4528+
// Convert the world space values of the interpolators to local space of the new parent
45104529
if (SynchronizePosition)
45114530
{
45124531
m_PositionInterpolator.ConvertTransformSpace(parentObject.transform, true);
@@ -4516,10 +4535,11 @@ internal void UpdateParenting(NetworkObjectReference parent, bool worldPositionS
45164535
m_RotationInterpolator.ConvertTransformSpace(parentObject.transform, true);
45174536
}
45184537
m_PreviousParent = parentObject;
4538+
// Always assure this is true
4539+
InLocalSpace = true;
45194540
}
45204541
else if (m_PreviousParent)
45214542
{
4522-
InLocalSpace = false;
45234543
// Convert everything back to world space values
45244544
if (SynchronizePosition)
45254545
{
@@ -4528,13 +4548,15 @@ internal void UpdateParenting(NetworkObjectReference parent, bool worldPositionS
45284548
}
45294549
if (SynchronizeRotation)
45304550
{
4531-
m_InternalCurrentRotation = m_PreviousParent.transform.localRotation * m_InternalCurrentRotation;
4551+
m_InternalCurrentRotation = m_PreviousParent.transform.localRotation * transform.localRotation;
45324552
m_RotationInterpolator.ConvertTransformSpace(m_PreviousParent.transform, false);
45334553
}
45344554
m_PreviousParent = null;
4555+
// Always assure this is false
4556+
InLocalSpace = false;
45354557
}
45364558

4537-
if (UseHalfFloatPrecision)
4559+
if (SynchronizePosition && UseHalfFloatPrecision)
45384560
{
45394561
m_HalfPositionState.UpdateFrom(ref m_InternalCurrentPosition, m_CachedNetworkManager.LocalTime.Tick);
45404562
}

0 commit comments

Comments
 (0)