Skip to content

Commit 45e80cb

Browse files
update and fix
Updated ApplyAuthoritativeState so that it is less complicated to follow. Fixed another issue discovered where the replicated network state values were being used for resetting interpolators during spawn initialization. Since the replicated network state only has the most recent deltas at the time the NetworkObject is serialized, this would cause "seemingly random" late joining issues.
1 parent 1dc67f5 commit 45e80cb

File tree

1 file changed

+62
-108
lines changed

1 file changed

+62
-108
lines changed

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

Lines changed: 62 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -534,15 +534,31 @@ private void TryCommitTransform(Transform transformToCommit, double dirtyTime)
534534
private void ResetInterpolatedStateToCurrentAuthoritativeState()
535535
{
536536
var serverTime = NetworkManager.ServerTime.Time;
537-
m_PositionXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionX, serverTime);
538-
m_PositionYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionY, serverTime);
539-
m_PositionZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionZ, serverTime);
540537

541-
m_RotationInterpolator.ResetTo(Quaternion.Euler(m_LocalAuthoritativeNetworkState.RotAngleX, m_LocalAuthoritativeNetworkState.RotAngleY, m_LocalAuthoritativeNetworkState.RotAngleZ), serverTime);
538+
// TODO: Look into a better way to communicate the entire state for late joining clients.
539+
// Since the replicated network state will just be the most recent deltas and not the entire state.
540+
//m_PositionXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionX, serverTime);
541+
//m_PositionYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionY, serverTime);
542+
//m_PositionZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.PositionZ, serverTime);
542543

543-
m_ScaleXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleX, serverTime);
544-
m_ScaleYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleY, serverTime);
545-
m_ScaleZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleZ, serverTime);
544+
//m_RotationInterpolator.ResetTo(Quaternion.Euler(m_LocalAuthoritativeNetworkState.RotAngleX, m_LocalAuthoritativeNetworkState.RotAngleY, m_LocalAuthoritativeNetworkState.RotAngleZ), serverTime);
545+
546+
//m_ScaleXInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleX, serverTime);
547+
//m_ScaleYInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleY, serverTime);
548+
//m_ScaleZInterpolator.ResetTo(m_LocalAuthoritativeNetworkState.ScaleZ, serverTime);
549+
550+
// NOTE ABOUT THIS CHANGE:
551+
// !!! This will exclude any scale changes because we currently do not spawn network objects with scale !!!
552+
// Regarding Scale: It will be the same scale as the default scale for the object being spawned.
553+
m_PositionXInterpolator.ResetTo(transform.position.x, serverTime);
554+
m_PositionYInterpolator.ResetTo(transform.position.y, serverTime);
555+
m_PositionZInterpolator.ResetTo(transform.position.z, serverTime);
556+
557+
m_RotationInterpolator.ResetTo(transform.rotation, serverTime);
558+
559+
m_ScaleXInterpolator.ResetTo(transform.localScale.x, serverTime);
560+
m_ScaleYInterpolator.ResetTo(transform.localScale.y, serverTime);
561+
m_ScaleZInterpolator.ResetTo(transform.localScale.z, serverTime);
546562
}
547563

548564
/// <summary>
@@ -675,144 +691,82 @@ private bool ApplyTransformToNetworkStateWithInfo(ref NetworkTransformState netw
675691
private void ApplyAuthoritativeState()
676692
{
677693
var networkState = ReplicatedNetworkState.Value;
678-
var interpolatedPosition = networkState.InLocalSpace ? transform.localPosition : transform.position;
694+
var adjustedPosition = networkState.InLocalSpace ? transform.localPosition : transform.position;
679695

680-
// todo: we should store network state w/ quats vs. euler angles
681-
var interpolatedRotAngles = networkState.InLocalSpace ? transform.localEulerAngles : transform.eulerAngles;
682-
var interpolatedScale = transform.localScale;
683-
var isTeleporting = networkState.IsTeleportingNextFrame;
696+
// TODO: We should store network state w/ quats vs. euler angles
697+
var adjustedRotAngles = networkState.InLocalSpace ? transform.localEulerAngles : transform.eulerAngles;
698+
var adjustedScale = transform.localScale;
684699

685700
// InLocalSpace Read:
686701
InLocalSpace = networkState.InLocalSpace;
687702

688-
// NOTE ABOUT INTERPOLATING AND BELOW CODE:
703+
// NOTE ABOUT INTERPOLATING AND THE CODE BELOW:
689704
// We always apply the interpolated state for any axis we are synchronizing even when the state has no deltas
690705
// to assure we fully interpolate to our target even after we stop extrapolating 1 tick later.
691-
692-
// Update the position values that were changed in this state update
693-
if (networkState.HasPositionX)
694-
{
695-
interpolatedPosition.x = isTeleporting || !Interpolate ? networkState.PositionX : m_PositionXInterpolator.GetInterpolatedValue();
696-
}
697-
else if (Interpolate && SyncPositionX)
706+
var useInterpolatedValue = !networkState.IsTeleportingNextFrame && Interpolate;
707+
if (!useInterpolatedValue)
698708
{
699-
interpolatedPosition.x = m_PositionXInterpolator.GetInterpolatedValue();
700-
}
709+
if (networkState.HasPositionX) { adjustedPosition.x = networkState.PositionX; }
710+
if (networkState.HasPositionY) { adjustedPosition.y = networkState.PositionY; }
711+
if (networkState.HasPositionZ) { adjustedPosition.z = networkState.PositionZ; }
701712

702-
if (networkState.HasPositionY)
703-
{
704-
interpolatedPosition.y = isTeleporting || !Interpolate ? networkState.PositionY : m_PositionYInterpolator.GetInterpolatedValue();
705-
}
706-
else if (Interpolate && SyncPositionY)
707-
{
708-
interpolatedPosition.y = m_PositionYInterpolator.GetInterpolatedValue();
709-
}
713+
if (networkState.HasScaleX) { adjustedScale.x = networkState.ScaleX; }
714+
if (networkState.HasScaleY) { adjustedScale.y = networkState.ScaleY; }
715+
if (networkState.HasScaleZ) { adjustedScale.z = networkState.ScaleZ; }
710716

711-
if (networkState.HasPositionZ)
712-
{
713-
interpolatedPosition.z = isTeleporting || !Interpolate ? networkState.PositionZ : m_PositionZInterpolator.GetInterpolatedValue();
717+
if (networkState.HasRotAngleX) { adjustedRotAngles.x = networkState.RotAngleX; }
718+
if (networkState.HasRotAngleY) { adjustedRotAngles.y = networkState.RotAngleY; }
719+
if (networkState.HasRotAngleZ) { adjustedRotAngles.z = networkState.RotAngleZ; }
714720
}
715-
else if (Interpolate && SyncPositionZ)
721+
else if (useInterpolatedValue)
716722
{
717-
interpolatedPosition.z = m_PositionZInterpolator.GetInterpolatedValue();
718-
}
723+
if (SyncPositionX) { adjustedPosition.x = m_PositionXInterpolator.GetInterpolatedValue(); }
724+
if (SyncPositionY) { adjustedPosition.y = m_PositionYInterpolator.GetInterpolatedValue(); }
725+
if (SyncPositionZ) { adjustedPosition.z = m_PositionZInterpolator.GetInterpolatedValue(); }
719726

720-
// Update the rotation values that were changed in this state update
721-
if (networkState.HasRotAngleChange)
722-
{
723-
var eulerAngles = Interpolate ? m_RotationInterpolator.GetInterpolatedValue().eulerAngles : new Vector3();
724-
if (networkState.HasRotAngleX)
725-
{
726-
interpolatedRotAngles.x = isTeleporting || !Interpolate ? networkState.RotAngleX : eulerAngles.x;
727-
}
727+
if (SyncScaleX) { adjustedScale.x = m_ScaleXInterpolator.GetInterpolatedValue(); }
728+
if (SyncScaleY) { adjustedScale.y = m_ScaleYInterpolator.GetInterpolatedValue(); }
729+
if (SyncScaleZ) { adjustedScale.z = m_ScaleZInterpolator.GetInterpolatedValue(); }
728730

729-
if (networkState.HasRotAngleY)
731+
if (SynchronizeRotation)
730732
{
731-
interpolatedRotAngles.y = isTeleporting || !Interpolate ? networkState.RotAngleY : eulerAngles.y;
733+
var interpolatedEulerAngles = m_RotationInterpolator.GetInterpolatedValue().eulerAngles;
734+
if (SyncRotAngleX) { adjustedRotAngles.x = interpolatedEulerAngles.x; }
735+
if (SyncRotAngleY) { adjustedRotAngles.y = interpolatedEulerAngles.y; }
736+
if (SyncRotAngleZ) { adjustedRotAngles.z = interpolatedEulerAngles.z; }
732737
}
733-
734-
if (networkState.HasRotAngleZ)
735-
{
736-
interpolatedRotAngles.z = isTeleporting || !Interpolate ? networkState.RotAngleZ : eulerAngles.z;
737-
}
738-
}
739-
else if (Interpolate && SynchronizeRotation)
740-
{
741-
var eulerAngles = m_RotationInterpolator.GetInterpolatedValue().eulerAngles;
742-
if (SyncRotAngleX)
743-
{
744-
interpolatedRotAngles.x = eulerAngles.x;
745-
}
746-
747-
if (SyncRotAngleY)
748-
{
749-
interpolatedRotAngles.y = eulerAngles.y;
750-
}
751-
752-
if (SyncRotAngleZ)
753-
{
754-
interpolatedRotAngles.z = eulerAngles.z;
755-
}
756-
}
757-
758-
// Update all scale axis that were changed in this state update
759-
if (networkState.HasScaleX)
760-
{
761-
interpolatedScale.x = isTeleporting || !Interpolate ? networkState.ScaleX : m_ScaleXInterpolator.GetInterpolatedValue();
762-
}
763-
else if (Interpolate && SyncScaleX)
764-
{
765-
interpolatedScale.x = m_ScaleXInterpolator.GetInterpolatedValue();
766-
}
767-
768-
if (networkState.HasScaleY)
769-
{
770-
interpolatedScale.y = isTeleporting || !Interpolate ? networkState.ScaleY : m_ScaleYInterpolator.GetInterpolatedValue();
771-
}
772-
else if (Interpolate && SyncScaleY)
773-
{
774-
interpolatedScale.y = m_ScaleYInterpolator.GetInterpolatedValue();
775-
}
776-
777-
if (networkState.HasScaleZ)
778-
{
779-
interpolatedScale.z = isTeleporting || !Interpolate ? networkState.ScaleZ : m_ScaleZInterpolator.GetInterpolatedValue();
780-
}
781-
else if (Interpolate && SyncScaleZ)
782-
{
783-
interpolatedScale.z = m_ScaleZInterpolator.GetInterpolatedValue();
784738
}
785739

786-
// Apply the new position
787-
if (networkState.HasPositionChange || (Interpolate && SynchronizePosition))
740+
// Apply the new position if it has changed or we are interpolating and synchronizing position
741+
if (networkState.HasPositionChange || (useInterpolatedValue && SynchronizePosition))
788742
{
789743
if (InLocalSpace)
790744
{
791-
transform.localPosition = interpolatedPosition;
745+
transform.localPosition = adjustedPosition;
792746
}
793747
else
794748
{
795-
transform.position = interpolatedPosition;
749+
transform.position = adjustedPosition;
796750
}
797751
}
798752

799-
// Apply the new rotation
800-
if (networkState.HasRotAngleChange || (Interpolate && SynchronizeRotation))
753+
// Apply the new rotation if it has changed or we are interpolating and synchronizing rotation
754+
if (networkState.HasRotAngleChange || (useInterpolatedValue && SynchronizeRotation))
801755
{
802756
if (InLocalSpace)
803757
{
804-
transform.localRotation = Quaternion.Euler(interpolatedRotAngles);
758+
transform.localRotation = Quaternion.Euler(adjustedRotAngles);
805759
}
806760
else
807761
{
808-
transform.rotation = Quaternion.Euler(interpolatedRotAngles);
762+
transform.rotation = Quaternion.Euler(adjustedRotAngles);
809763
}
810764
}
811765

812-
// Apply the new scale
813-
if (networkState.HasScaleChange || (Interpolate && SynchronizeScale))
766+
// Apply the new scale if it has changed or we are interpolating and synchronizing scale
767+
if (networkState.HasScaleChange || (useInterpolatedValue && SynchronizeScale))
814768
{
815-
transform.localScale = interpolatedScale;
769+
transform.localScale = adjustedScale;
816770
}
817771
}
818772

0 commit comments

Comments
 (0)