From 3b7d98a58e9d684a69bf53c6442baa4c107dcefb Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 11:31:24 -0500 Subject: [PATCH 01/17] fix NetworkTransform was setting the value of m_Bitset but not resetting the individual bits if there was no deltas. This would result in a gradually increasing message size over time when updating the NetworkTransform. --- .../Components/NetworkTransform.cs | 218 +++++++++++------- 1 file changed, 137 insertions(+), 81 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 82c1ab8b2c..d2a3eb0f79 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -62,118 +62,118 @@ internal struct NetworkTransformState : INetworkSerializable private const int k_TeleportingBit = 10; // 11-15: - private ushort m_Bitset; + internal ushort Bitset; internal bool InLocalSpace { - get => (m_Bitset & (1 << k_InLocalSpaceBit)) != 0; + get => (Bitset & (1 << k_InLocalSpaceBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_InLocalSpaceBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_InLocalSpaceBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_InLocalSpaceBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_InLocalSpaceBit)); } } } // Position internal bool HasPositionX { - get => (m_Bitset & (1 << k_PositionXBit)) != 0; + get => (Bitset & (1 << k_PositionXBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionXBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionXBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionXBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_PositionXBit)); } } } internal bool HasPositionY { - get => (m_Bitset & (1 << k_PositionYBit)) != 0; + get => (Bitset & (1 << k_PositionYBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionYBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionYBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionYBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_PositionYBit)); } } } internal bool HasPositionZ { - get => (m_Bitset & (1 << k_PositionZBit)) != 0; + get => (Bitset & (1 << k_PositionZBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionZBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionZBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionZBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_PositionZBit)); } } } // RotAngles internal bool HasRotAngleX { - get => (m_Bitset & (1 << k_RotAngleXBit)) != 0; + get => (Bitset & (1 << k_RotAngleXBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleXBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleXBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleXBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleXBit)); } } } internal bool HasRotAngleY { - get => (m_Bitset & (1 << k_RotAngleYBit)) != 0; + get => (Bitset & (1 << k_RotAngleYBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleYBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleYBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleYBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleYBit)); } } } internal bool HasRotAngleZ { - get => (m_Bitset & (1 << k_RotAngleZBit)) != 0; + get => (Bitset & (1 << k_RotAngleZBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleZBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleZBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleZBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleZBit)); } } } // Scale internal bool HasScaleX { - get => (m_Bitset & (1 << k_ScaleXBit)) != 0; + get => (Bitset & (1 << k_ScaleXBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleXBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleXBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleXBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleXBit)); } } } internal bool HasScaleY { - get => (m_Bitset & (1 << k_ScaleYBit)) != 0; + get => (Bitset & (1 << k_ScaleYBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleYBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleYBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleYBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleYBit)); } } } internal bool HasScaleZ { - get => (m_Bitset & (1 << k_ScaleZBit)) != 0; + get => (Bitset & (1 << k_ScaleZBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleZBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleZBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleZBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleZBit)); } } } internal bool IsTeleportingNextFrame { - get => (m_Bitset & (1 << k_TeleportingBit)) != 0; + get => (Bitset & (1 << k_TeleportingBit)) != 0; set { - if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_TeleportingBit)); } - else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_TeleportingBit)); } + if (value) { Bitset = (ushort)(Bitset | (1 << k_TeleportingBit)); } + else { Bitset = (ushort)(Bitset & ~(1 << k_TeleportingBit)); } } } @@ -219,7 +219,7 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade { serializer.SerializeValue(ref SentTime); // InLocalSpace + HasXXX Bits - serializer.SerializeValue(ref m_Bitset); + serializer.SerializeValue(ref Bitset); // Position Values if (HasPositionX) { @@ -523,76 +523,130 @@ internal bool ApplyTransformToNetworkState(ref NetworkTransformState networkStat // this still is overly costly and could use more improvements. // // (ditto for scale components) - if (SyncPositionX && - Mathf.Abs(networkState.PositionX - position.x) > PositionThreshold) + if (SyncPositionX) { - networkState.PositionX = position.x; - networkState.HasPositionX = true; - isPositionDirty = true; + if (Mathf.Abs(networkState.PositionX - position.x) > PositionThreshold) + { + networkState.PositionX = position.x; + networkState.HasPositionX = true; + isPositionDirty = true; + } + else + { + networkState.HasPositionX = false; + } } - if (SyncPositionY && - Mathf.Abs(networkState.PositionY - position.y) > PositionThreshold) + if (SyncPositionY) { - networkState.PositionY = position.y; - networkState.HasPositionY = true; - isPositionDirty = true; + if (Mathf.Abs(networkState.PositionY - position.y) > PositionThreshold) + { + networkState.PositionY = position.y; + networkState.HasPositionY = true; + isPositionDirty = true; + } + else + { + networkState.HasPositionY = false; + } } - if (SyncPositionZ && - Mathf.Abs(networkState.PositionZ - position.z) > PositionThreshold) + if (SyncPositionZ) { - networkState.PositionZ = position.z; - networkState.HasPositionZ = true; - isPositionDirty = true; + if (Mathf.Abs(networkState.PositionZ - position.z) > PositionThreshold) + { + networkState.PositionZ = position.z; + networkState.HasPositionZ = true; + isPositionDirty = true; + } + else + { + networkState.HasPositionZ = false; + } } - if (SyncRotAngleX && - Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleX, rotAngles.x)) > RotAngleThreshold) + if (SyncRotAngleX) { - networkState.RotAngleX = rotAngles.x; - networkState.HasRotAngleX = true; - isRotationDirty = true; + if (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleX, rotAngles.x)) > RotAngleThreshold) + { + networkState.RotAngleX = rotAngles.x; + networkState.HasRotAngleX = true; + isRotationDirty = true; + } + else + { + networkState.HasRotAngleX = false; + } } - if (SyncRotAngleY && - Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleY, rotAngles.y)) > RotAngleThreshold) + if (SyncRotAngleY) { - networkState.RotAngleY = rotAngles.y; - networkState.HasRotAngleY = true; - isRotationDirty = true; + if (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleY, rotAngles.y)) > RotAngleThreshold) + { + networkState.RotAngleY = rotAngles.y; + networkState.HasRotAngleY = true; + isRotationDirty = true; + } + else + { + networkState.HasRotAngleY = false; + } } - if (SyncRotAngleZ && - Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleZ, rotAngles.z)) > RotAngleThreshold) + if (SyncRotAngleZ) { - networkState.RotAngleZ = rotAngles.z; - networkState.HasRotAngleZ = true; - isRotationDirty = true; + if (Mathf.Abs(Mathf.DeltaAngle(networkState.RotAngleZ, rotAngles.z)) > RotAngleThreshold) + { + networkState.RotAngleZ = rotAngles.z; + networkState.HasRotAngleZ = true; + isRotationDirty = true; + } + else + { + networkState.HasRotAngleZ = false; + } } - if (SyncScaleX && - Mathf.Abs(networkState.ScaleX - scale.x) > ScaleThreshold) + if (SyncScaleX) { - networkState.ScaleX = scale.x; - networkState.HasScaleX = true; - isScaleDirty = true; + if (Mathf.Abs(networkState.ScaleX - scale.x) > ScaleThreshold) + { + networkState.ScaleX = scale.x; + networkState.HasScaleX = true; + isScaleDirty = true; + } + else + { + networkState.HasScaleX = false; + } } - if (SyncScaleY && - Mathf.Abs(networkState.ScaleY - scale.y) > ScaleThreshold) + if (SyncScaleY) { - networkState.ScaleY = scale.y; - networkState.HasScaleY = true; - isScaleDirty = true; + if (Mathf.Abs(networkState.ScaleY - scale.y) > ScaleThreshold) + { + networkState.ScaleY = scale.y; + networkState.HasScaleY = true; + isScaleDirty = true; + } + else + { + networkState.HasScaleY = false; + } } - if (SyncScaleZ && - Mathf.Abs(networkState.ScaleZ - scale.z) > ScaleThreshold) + if (SyncScaleZ) { - networkState.ScaleZ = scale.z; - networkState.HasScaleZ = true; - isScaleDirty = true; + if (Mathf.Abs(networkState.ScaleZ - scale.z) > ScaleThreshold) + { + networkState.ScaleZ = scale.z; + networkState.HasScaleZ = true; + isScaleDirty = true; + } + else + { + networkState.HasScaleZ = false; + } } isDirty |= isPositionDirty || isRotationDirty || isScaleDirty; @@ -858,11 +912,13 @@ public override void OnNetworkSpawn() m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; + + m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; if (CanCommitToTransform) { TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } - m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; + // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object From 19a4c88765fad4e68f7e65d86db565bf5b7a9ccc Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 11:46:06 -0500 Subject: [PATCH 02/17] update migrating the assignment back down below the CanCommitToTransform --- com.unity.netcode.gameobjects/Components/NetworkTransform.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index d2a3eb0f79..65bd338f56 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -912,13 +912,11 @@ public override void OnNetworkSpawn() m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; - - m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; if (CanCommitToTransform) { TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } - + m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object From 6150b21a39ff9c9d0b6dda9d4e16cee82685d163 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 14:22:09 -0500 Subject: [PATCH 03/17] fix This resolves the issue where clients were applying every value marked to be synchronized even if the update didn't include specific axis values. --- .../Components/NetworkTransform.cs | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 65bd338f56..2094585dcc 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -659,7 +659,18 @@ internal bool ApplyTransformToNetworkState(ref NetworkTransformState networkStat return (isDirty, isPositionDirty, isRotationDirty, isScaleDirty); } - private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState networkState, Transform transformToUpdate) + /// + /// Applies the authoritative state to the local transform + /// + /// + /// The serverTime is required for position and scale in order to prevent a single element of each 3 elements + /// from having too large of a delta time between the time it was last updated and the time any new update is + /// sent. + /// + /// new state to apply + /// transform to update + /// required to interpolate when axis is not updated in the state to apply + private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState networkState, Transform transformToUpdate, double serverTime) { var interpolatedPosition = InLocalSpace ? transformToUpdate.localPosition : transformToUpdate.position; @@ -670,23 +681,35 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw // InLocalSpace Read InLocalSpace = networkState.InLocalSpace; // Position Read - if (SyncPositionX) + if (networkState.HasPositionX) { interpolatedPosition.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.x : m_PositionXInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_PositionXInterpolator.AddMeasurement(interpolatedPosition.x, serverTime); + } - if (SyncPositionY) + if (networkState.HasPositionY) { interpolatedPosition.y = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.y : m_PositionYInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_PositionYInterpolator.AddMeasurement(interpolatedPosition.y, serverTime); + } - if (SyncPositionZ) + if (networkState.HasPositionZ) { interpolatedPosition.z = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.z : m_PositionZInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_PositionZInterpolator.AddMeasurement(interpolatedPosition.z, serverTime); + } // again, we should be using quats here - if (SyncRotAngleX || SyncRotAngleY || SyncRotAngleZ) + if (networkState.HasRotAngleX || networkState.HasRotAngleY || networkState.HasRotAngleZ) { var eulerAngles = new Vector3(); if (Interpolate) @@ -694,43 +717,56 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw eulerAngles = m_RotationInterpolator.GetInterpolatedValue().eulerAngles; } - if (SyncRotAngleX) + if (networkState.HasRotAngleX) { interpolatedRotAngles.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Rotation.x : eulerAngles.x; } - if (SyncRotAngleY) + if (networkState.HasRotAngleY) { interpolatedRotAngles.y = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Rotation.y : eulerAngles.y; } - if (SyncRotAngleZ) + if (networkState.HasRotAngleZ) { interpolatedRotAngles.z = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Rotation.z : eulerAngles.z; } } // Scale Read - if (SyncScaleX) + if (networkState.HasScaleX) { interpolatedScale.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.x : m_ScaleXInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_ScaleXInterpolator.AddMeasurement(interpolatedScale.x, serverTime); + } - if (SyncScaleY) + if (networkState.HasScaleY) { interpolatedScale.y = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.y : m_ScaleYInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_ScaleYInterpolator.AddMeasurement(interpolatedScale.x, serverTime); + } - if (SyncScaleZ) + if (networkState.HasScaleZ) { interpolatedScale.z = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.z : m_ScaleZInterpolator.GetInterpolatedValue(); } + else if (Interpolate) + { + m_ScaleZInterpolator.AddMeasurement(interpolatedScale.x, serverTime); + } // Position Apply - if (SyncPositionX || SyncPositionY || SyncPositionZ) + if (networkState.HasPositionX || networkState.HasPositionY || networkState.HasPositionZ) { if (InLocalSpace) { + transformToUpdate.localPosition = interpolatedPosition; } else @@ -740,7 +776,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw } // RotAngles Apply - if (SyncRotAngleX || SyncRotAngleY || SyncRotAngleZ) + if (networkState.HasRotAngleX || networkState.HasRotAngleY || networkState.HasRotAngleZ) { if (InLocalSpace) { @@ -753,7 +789,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw } // Scale Apply - if (SyncScaleX || SyncScaleY || SyncScaleZ) + if (networkState.HasScaleX || networkState.HasScaleY || networkState.HasScaleZ) { transformToUpdate.localScale = interpolatedScale; } @@ -850,11 +886,6 @@ private void OnNetworkStateChanged(NetworkTransformState oldState, NetworkTransf AddInterpolatedState(newState, (newState.InLocalSpace != m_LastInterpolateLocal)); } m_LastInterpolateLocal = newState.InLocalSpace; - - if (m_CachedNetworkManager.LogLevel == LogLevel.Developer) - { - var pos = new Vector3(newState.PositionX, newState.PositionY, newState.PositionZ); - } } /// @@ -912,11 +943,11 @@ public override void OnNetworkSpawn() m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; + m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; if (CanCommitToTransform) { TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } - m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object @@ -951,7 +982,7 @@ private void Initialize() } else if (m_Transform != null) { - ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform); + ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform, NetworkManager.ServerTime.Time); } } @@ -1065,7 +1096,7 @@ protected virtual void Update() if (!CanCommitToTransform) { // Apply updated interpolated value - ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform); + ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform, serverTime.Time); } } m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = false; @@ -1091,7 +1122,7 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca stateToSend.Position = newPosition; stateToSend.Rotation = newRotationEuler; stateToSend.Scale = newScale; - ApplyInterpolatedNetworkStateToTransform(stateToSend, transform); + ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); // set teleport flag in state to signal to ghosts not to interpolate m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = true; // check server side From 11ddbd73c74e2a6897184eb09b341567111ada30 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 14:23:48 -0500 Subject: [PATCH 04/17] test This includes some fixes to prefabs that hadn't been updated to the more recent changes in NetworkTransform that limited the minimum threshold (i.e. they were set to 0 which causes issues) --- ...bjectToOverride-VariantBlueCylinder.prefab | 5 + testproject/Assets/Prefabs/Player.prefab | 11 +- .../AdditiveSceneMultiInstance.unity | 65 +++- .../SceneTransitioningBase1.unity | 305 +++++++++--------- 4 files changed, 232 insertions(+), 154 deletions(-) diff --git a/testproject/Assets/Prefabs/ObjectToOverride-VariantBlueCylinder.prefab b/testproject/Assets/Prefabs/ObjectToOverride-VariantBlueCylinder.prefab index d584980843..6bcfbaca76 100644 --- a/testproject/Assets/Prefabs/ObjectToOverride-VariantBlueCylinder.prefab +++ b/testproject/Assets/Prefabs/ObjectToOverride-VariantBlueCylinder.prefab @@ -82,5 +82,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: 29cabf623d47bb345a9bb4140e4397d7, + type: 3} + propertyPath: PositionThreshold + value: 0.01 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 29cabf623d47bb345a9bb4140e4397d7, type: 3} diff --git a/testproject/Assets/Prefabs/Player.prefab b/testproject/Assets/Prefabs/Player.prefab index 82e49fd5c8..fbb2e970a4 100644 --- a/testproject/Assets/Prefabs/Player.prefab +++ b/testproject/Assets/Prefabs/Player.prefab @@ -36,6 +36,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 5, y: 0.625, z: 5} m_LocalScale: {x: 1.25, y: 1.25, z: 1.25} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3519470446676406143} m_Father: {fileID: 0} @@ -62,12 +63,11 @@ MonoBehaviour: SyncScaleX: 1 SyncScaleY: 1 SyncScaleZ: 1 - PositionThreshold: 0 - RotAngleThreshold: 0 - ScaleThreshold: 0 + PositionThreshold: 0.01 + RotAngleThreshold: 0.01 + ScaleThreshold: 0.1 InLocalSpace: 0 Interpolate: 1 - FixedSendsPerSecond: 15 --- !u!114 &-3775814466963834669 MonoBehaviour: m_ObjectHideFlags: 0 @@ -103,6 +103,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -239,6 +240,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1.045, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4079352819444256611} m_RootOrder: 0 @@ -262,6 +264,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/AdditiveSceneMultiInstance.unity b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/AdditiveSceneMultiInstance.unity index 6ea9d5e74b..a762b39af1 100644 --- a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/AdditiveSceneMultiInstance.unity +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/AdditiveSceneMultiInstance.unity @@ -195,6 +195,21 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: ScaleThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: PositionThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: RotAngleThreshold + value: 0.1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: ea906834639fa3f4ba65c95db6181d6b, type: 3} --- !u!1001 &365996112 @@ -269,6 +284,21 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: ScaleThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: PositionThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: RotAngleThreshold + value: 0.1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: ea906834639fa3f4ba65c95db6181d6b, type: 3} --- !u!850595691 &903034822 @@ -278,7 +308,7 @@ LightingSettings: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: - serializedVersion: 3 + serializedVersion: 4 m_GIWorkflowMode: 1 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 0 @@ -291,7 +321,7 @@ LightingSettings: m_LightmapMaxSize: 1024 m_BakeResolution: 40 m_Padding: 2 - m_TextureCompression: 1 + m_LightmapCompression: 3 m_AO: 0 m_AOMaxDistance: 1 m_CompAOExponent: 1 @@ -332,6 +362,7 @@ LightingSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 + m_PVRTiledBaking: 0 --- !u!1001 &1152084533 PrefabInstance: m_ObjectHideFlags: 0 @@ -404,6 +435,21 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: ScaleThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: PositionThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: RotAngleThreshold + value: 0.1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: ea906834639fa3f4ba65c95db6181d6b, type: 3} --- !u!1001 &1247056486 @@ -478,5 +524,20 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: ScaleThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: PositionThreshold + value: 0.01 + objectReference: {fileID: 0} + - target: {fileID: 4600632750638426092, guid: ea906834639fa3f4ba65c95db6181d6b, + type: 3} + propertyPath: RotAngleThreshold + value: 0.1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: ea906834639fa3f4ba65c95db6181d6b, type: 3} diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity index bf5d0be2c7..fb56264016 100644 --- a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity @@ -171,8 +171,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveSceneMultiInstance m_SceneAsset: {fileID: 102900000, guid: 0ae94f636016d3b40bfbecad57d99553, type: 3} @@ -224,12 +224,13 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 244f0414ea8419b41ac51adb305d64b0, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_SwitchSceneButtonObject: {fileID: 1347823141} m_SceneToSwitchTo: SceneTransitioningBase2 m_EnableAutoSwitch: 0 m_AutoSwitchTimeOut: 60 + DisconnectClientUponLoadScene: 0 --- !u!1 &37242881 GameObject: m_ObjectHideFlags: 0 @@ -379,8 +380,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -455,8 +456,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -632,8 +633,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveSceneMultiInstance m_SceneAsset: {fileID: 102900000, guid: 0ae94f636016d3b40bfbecad57d99553, type: 3} @@ -686,8 +687,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -762,8 +763,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -823,8 +824,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_IgnoreReversedGraphics: 1 m_BlockingObjects: 0 m_BlockingMask: @@ -840,8 +841,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_UiScaleMode: 0 m_ReferencePixelsPerUnit: 100 m_ScaleFactor: 1 @@ -924,8 +925,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_IgnoreReversedGraphics: 1 m_BlockingObjects: 0 m_BlockingMask: @@ -941,8 +942,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_UiScaleMode: 1 m_ReferencePixelsPerUnit: 100 m_ScaleFactor: 1 @@ -1055,8 +1056,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveScene2 m_SceneAsset: {fileID: 102900000, guid: c6a3d883c8253ee43bca4f2b03797d7b, type: 3} @@ -1109,8 +1110,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -1156,7 +1157,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -1306,8 +1307,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -1353,7 +1354,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -1406,8 +1407,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -1482,8 +1483,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -1558,8 +1559,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.9811321, g: 0.9811321, b: 0.9811321, a: 1} m_RaycastTarget: 1 @@ -1722,8 +1723,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.5058824, b: 0.003921569, a: 1} m_RaycastTarget: 1 @@ -1802,8 +1803,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -1878,8 +1879,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -1954,8 +1955,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -2030,8 +2031,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveScene1 m_SceneAsset: {fileID: 102900000, guid: 41a0239b0c49e2047b7063c822f0df8a, type: 3} @@ -2041,8 +2042,8 @@ LightingSettings: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: - serializedVersion: 3 + m_Name: + serializedVersion: 4 m_GIWorkflowMode: 1 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 0 @@ -2145,8 +2146,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -2299,8 +2300,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveSceneMultiInstance m_SceneAsset: {fileID: 102900000, guid: 0ae94f636016d3b40bfbecad57d99553, type: 3} @@ -2313,10 +2314,10 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 1024114720} - - component: {fileID: 1024114719} - component: {fileID: 1024114718} - component: {fileID: 1024114721} - component: {fileID: 1024114722} + - component: {fileID: 1024114723} m_Layer: 0 m_Name: NetworkManager m_TagString: Untagged @@ -2334,13 +2335,13 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 593a2fe42fa9d37498c96f9a383b6521, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: RunInBackground: 1 LogLevel: 1 NetworkConfig: ProtocolVersion: 0 - NetworkTransport: {fileID: 1024114719} + NetworkTransport: {fileID: 1024114723} PlayerPrefab: {fileID: 4079352819444256614, guid: c16f03336b6104576a565ef79ad643c0, type: 3} NetworkPrefabs: @@ -2397,7 +2398,7 @@ MonoBehaviour: TickRate: 30 ClientConnectionBufferTimeout: 10 ConnectionApproval: 0 - ConnectionData: + ConnectionData: EnableTimeResync: 0 TimeResyncInterval: 30 EnsureNetworkVariableLengthSafety: 0 @@ -2409,25 +2410,6 @@ MonoBehaviour: LoadSceneTimeOut: 120 SpawnTimeout: 1 EnableNetworkLogs: 1 ---- !u!114 &1024114719 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1024114717} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: b84c2d8dfe509a34fb59e2b81f8e1319, type: 3} - m_Name: - m_EditorClassIdentifier: - MessageBufferSize: 65535 - MaxConnections: 100 - MaxSentMessageQueueSize: 512 - ConnectAddress: 127.0.0.1 - ConnectPort: 7777 - ServerListenPort: 7777 - MessageSendMode: 0 --- !u!4 &1024114720 Transform: m_ObjectHideFlags: 0 @@ -2453,8 +2435,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0e6f8504d891fc44881b2d9703017d03, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: --- !u!114 &1024114722 MonoBehaviour: m_ObjectHideFlags: 0 @@ -2465,10 +2447,38 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 71c52a32bd1c1c84691050b6d045ab4a, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: LogToConsole: 1 TimeToLive: 10 +--- !u!114 &1024114723 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1024114717} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6960e84d07fb87f47956e7a81d71c4e6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ProtocolType: 0 + m_MaxPacketQueueSize: 128 + m_MaxPayloadSize: 512000 + m_MaxSendQueueSize: 4096000 + m_HeartbeatTimeoutMS: 500 + m_ConnectTimeoutMS: 1000 + m_MaxConnectAttempts: 60 + m_DisconnectTimeoutMS: 30000 + ConnectionData: + Address: 127.0.0.1 + Port: 7777 + ServerListenAddress: + DebugSimulator: + PacketDelayMS: 0 + PacketJitterMS: 0 + PacketDropRate: 0 --- !u!1 &1113539278 GameObject: m_ObjectHideFlags: 0 @@ -2497,8 +2507,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 8c48ea35c67e64f7fac22a3f6831ca88, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: AutoSpawnEnable: 1 InitialSpawnDelay: 0.2 SpawnsPerSecond: 1 @@ -2538,8 +2548,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: GlobalObjectIdHash: 1983031731 AlwaysReplicateAsRoot: 0 DontDestroyWithOwner: 0 @@ -2592,8 +2602,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 475de064003ff104fb88b1fbccd0f417, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ActivateOnLoad: 0 m_SceneToLoad: AdditiveSceneMultiInstance m_SceneAsset: {fileID: 102900000, guid: 0ae94f636016d3b40bfbecad57d99553, type: 3} @@ -2645,8 +2655,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -2726,8 +2736,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -2935,8 +2945,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3017,8 +3027,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -3060,7 +3070,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 --- !u!114 &1347823144 @@ -3073,8 +3083,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.1981132, g: 0.1981132, b: 0.1981132, a: 1} m_RaycastTarget: 1 @@ -3150,8 +3160,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -3197,7 +3207,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -3249,8 +3259,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.990566, g: 0.990566, b: 0.990566, a: 1} m_RaycastTarget: 1 @@ -3367,8 +3377,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3443,8 +3453,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3519,8 +3529,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3595,8 +3605,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3673,8 +3683,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -3716,7 +3726,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 --- !u!114 &1588117330 @@ -3729,8 +3739,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.1981132, g: 0.1981132, b: 0.1981132, a: 1} m_RaycastTarget: 1 @@ -3805,8 +3815,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -3886,8 +3896,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -3933,7 +3943,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -3986,8 +3996,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -4033,7 +4043,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -4086,8 +4096,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -4162,8 +4172,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -4218,8 +4228,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -4237,8 +4247,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_FirstSelected: {fileID: 0} m_sendNavigationEvents: 1 m_DragThreshold: 10 @@ -4305,8 +4315,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 0.5058824, b: 0.003921569, a: 1} m_RaycastTarget: 1 @@ -4645,8 +4655,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -4692,7 +4702,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 m_IsOn: 0 @@ -4744,8 +4754,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 @@ -4920,8 +4930,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Navigation: m_Mode: 3 m_WrapAround: 0 @@ -4970,7 +4980,7 @@ MonoBehaviour: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_IntArgument: 0 m_FloatArgument: 0 - m_StringArgument: + m_StringArgument: m_BoolArgument: 0 m_CallState: 2 --- !u!1 &2107482020 @@ -5016,11 +5026,10 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: cb5f3e55f5dd247129d8a4979b80ebbb, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_ClientServerToggle: {fileID: 1588117327} m_TrackSceneEvents: 1 - m_LogSceneEventsToConsole: 1 --- !u!114 &2107482023 MonoBehaviour: m_ObjectHideFlags: 0 @@ -5031,8 +5040,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: GlobalObjectIdHash: 3197939627 AlwaysReplicateAsRoot: 0 DontDestroyWithOwner: 0 @@ -5162,7 +5171,7 @@ PrefabInstance: - target: {fileID: 2848221157716786269, guid: 3200770c16e3b2b4ebe7f604154faac7, type: 3} propertyPath: m_FontData.m_Font - value: + value: objectReference: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - target: {fileID: 2848221157716786269, guid: 3200770c16e3b2b4ebe7f604154faac7, type: 3} @@ -5197,7 +5206,7 @@ PrefabInstance: - target: {fileID: 5266522511616468950, guid: 3200770c16e3b2b4ebe7f604154faac7, type: 3} propertyPath: m_SceneMenuToLoad - value: + value: objectReference: {fileID: 11400000, guid: c10d995498e0c514a853c3506031d3fb, type: 2} m_RemovedComponents: [] From 053ee6e0d36d08e876e67ebd5a25fcff6617c6ca Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 15:27:23 -0500 Subject: [PATCH 05/17] fix Since we are now no longer sending the entire transform values, this addition prevents the non-authoritative side from making changes to the transform. --- .../Components/NetworkTransform.cs | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 2094585dcc..c5c531add1 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -681,7 +681,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw // InLocalSpace Read InLocalSpace = networkState.InLocalSpace; // Position Read - if (networkState.HasPositionX) + if (networkState.HasPositionX ) { interpolatedPosition.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.x : m_PositionXInterpolator.GetInterpolatedValue(); } @@ -929,6 +929,34 @@ private void Awake() } } + /// + /// These local values are for the non-authoritative side + /// This prevents non-authoritative instances from changing + /// the transform. + /// + private Vector3 m_LocalPosition; + private Vector3 m_LocalScale; + private Quaternion m_LocalRotation; + + /// + /// Applies the last authorized position, scale, and rotation + /// + private void ApplyTransformValues() + { + m_Transform.position = m_LocalPosition; + m_Transform.localScale = m_LocalScale; + m_Transform.rotation = m_LocalRotation; + } + + /// + /// Sets the currently authorized position, scale, and rotation + /// + private void SetTransformValues() + { + m_LocalPosition = m_Transform.position; + m_LocalScale = m_Transform.localScale; + m_LocalRotation = m_Transform.rotation; + } /// public override void OnNetworkSpawn() @@ -948,6 +976,11 @@ public override void OnNetworkSpawn() { TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } + else + { + // For the non-authoritative side, we need to capture these values + SetTransformValues(); + } // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object @@ -1073,6 +1106,10 @@ protected virtual void Update() TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } } + else + { + ApplyTransformValues(); + } // apply interpolated value if (m_CachedNetworkManager.IsConnectedClient || m_CachedNetworkManager.IsListening) @@ -1095,8 +1132,15 @@ protected virtual void Update() if (!CanCommitToTransform) { + // Always update from the last transform values before updating from the transform state to assure + // no non-authoritative changes are allowed + ApplyTransformValues(); + // Apply updated interpolated value ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform, serverTime.Time); + + // Always set the any new transform values to assure only the authoritative side is updating the transform + SetTransformValues(); } } m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = false; From 4d4c658436b8135a94c79ebca7d0dd2c1c6692f1 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Wed, 3 Aug 2022 15:27:44 -0500 Subject: [PATCH 06/17] style removing whitespace --- com.unity.netcode.gameobjects/Components/NetworkTransform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index c5c531add1..9cfe282677 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -681,7 +681,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw // InLocalSpace Read InLocalSpace = networkState.InLocalSpace; // Position Read - if (networkState.HasPositionX ) + if (networkState.HasPositionX) { interpolatedPosition.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.x : m_PositionXInterpolator.GetInterpolatedValue(); } From 4744ee6ce49176a71fbc0f172122502d92ef5678 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:49:48 -0500 Subject: [PATCH 07/17] update Adding some test adjustments and including rotation to interpolation measurements. --- .../Components/NetworkTransform.cs | 15 ++- .../NetworkTransform/NetworkTransformTests.cs | 117 +++++++++++++++--- 2 files changed, 111 insertions(+), 21 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 9cfe282677..458b109004 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -368,6 +368,11 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade private readonly NetworkVariable m_ReplicatedNetworkState = new NetworkVariable(new NetworkTransformState()); + internal NetworkVariable GetReplicatedNetworkState() + { + return m_ReplicatedNetworkState; + } + private NetworkTransformState m_LocalAuthoritativeNetworkState; private const int k_DebugDrawLineTime = 10; @@ -388,6 +393,11 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade private int m_LastSentTick; private NetworkTransformState m_LastSentState; + internal NetworkTransformState GetLastSentState() + { + return m_LastSentState; + } + /// /// Tries updating the server authoritative transform, only if allowed. /// If this called server side, this will commit directly. @@ -850,7 +860,10 @@ private void AddInterpolatedState(NetworkTransformState newState, bool reset = f m_PositionZInterpolator.AddMeasurement(newState.PositionZ, sentTime); } - m_RotationInterpolator.AddMeasurement(Quaternion.Euler(newState.Rotation), sentTime); + if (newState.HasRotAngleX || newState.HasRotAngleY || newState.HasRotAngleZ) + { + m_RotationInterpolator.AddMeasurement(Quaternion.Euler(newState.Rotation), sentTime); + } if (newState.HasScaleX) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index 0d6c58ff4e..0f6590a657 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -57,7 +57,7 @@ protected override void OnCreatePlayerPrefab() else { var networkTransform = m_PlayerPrefab.AddComponent(); - networkTransform.Interpolate = false; + networkTransform.Interpolate = true; } } @@ -74,8 +74,8 @@ protected override void OnServerAndClientsCreated() protected override IEnumerator OnServerAndClientsConnected() { // Get the client player representation on both the server and the client side - m_ServerSideClientPlayer = m_PlayerNetworkObjects[m_ServerNetworkManager.LocalClientId][m_ClientNetworkManagers[0].LocalClientId]; - m_ClientSideClientPlayer = m_PlayerNetworkObjects[m_ClientNetworkManagers[0].LocalClientId][m_ClientNetworkManagers[0].LocalClientId]; + m_ServerSideClientPlayer = m_ServerNetworkManager.ConnectedClients[m_ClientNetworkManagers[0].LocalClientId].PlayerObject; + m_ClientSideClientPlayer = m_ClientNetworkManagers[0].LocalClient.PlayerObject; // Get the NetworkTransformTestComponent to make sure the client side is ready before starting test var otherSideNetworkTransformComponent = m_ClientSideClientPlayer.GetComponent(); @@ -118,38 +118,38 @@ public IEnumerator TestAuthoritativeTransformChangeOneAtATime([Values] bool test authPlayerTransform.position = new Vector3(10, 20, 30); - yield return WaitForConditionOrTimeOut(() => otherSideNetworkTransform.transform.position.x > approximation); + yield return WaitForConditionOrTimeOut(ServerClientPositionMatches); - Assert.False(s_GlobalTimeoutHelper.TimedOut, $"timeout while waiting for position change! Otherside value {otherSideNetworkTransform.transform.position.x} vs. Approximation {approximation}"); + AssertOnTimeout($"timeout while waiting for position change! Otherside value {otherSideNetworkTransform.transform.position.x} vs. Approximation {approximation}"); - Assert.True(new Vector3(10, 20, 30) == otherSideNetworkTransform.transform.position, $"wrong position on ghost, {otherSideNetworkTransform.transform.position}"); // Vector3 already does float approximation with == + //Assert.True(new Vector3(10, 20, 30) == otherSideNetworkTransform.transform.position, $"wrong position on ghost, {otherSideNetworkTransform.transform.position}"); // Vector3 already does float approximation with == // test rotation authPlayerTransform.rotation = Quaternion.Euler(45, 40, 35); // using euler angles instead of quaternions directly to really see issues users might encounter Assert.AreEqual(Quaternion.identity, otherSideNetworkTransform.transform.rotation, "wrong initial value for rotation"); // sanity check - yield return WaitForConditionOrTimeOut(() => otherSideNetworkTransform.transform.rotation.eulerAngles.x > approximation); + yield return WaitForConditionOrTimeOut(ServerClientRotationMatches); - Assert.False(s_GlobalTimeoutHelper.TimedOut, "timeout while waiting for rotation change"); + AssertOnTimeout("timeout while waiting for rotation change"); - // approximation needed here since eulerAngles isn't super precise. - Assert.LessOrEqual(Math.Abs(45 - otherSideNetworkTransform.transform.rotation.eulerAngles.x), approximation, $"wrong rotation on ghost on x, got {otherSideNetworkTransform.transform.rotation.eulerAngles.x}"); - Assert.LessOrEqual(Math.Abs(40 - otherSideNetworkTransform.transform.rotation.eulerAngles.y), approximation, $"wrong rotation on ghost on y, got {otherSideNetworkTransform.transform.rotation.eulerAngles.y}"); - Assert.LessOrEqual(Math.Abs(35 - otherSideNetworkTransform.transform.rotation.eulerAngles.z), approximation, $"wrong rotation on ghost on z, got {otherSideNetworkTransform.transform.rotation.eulerAngles.z}"); + //// approximation needed here since eulerAngles isn't super precise. + //Assert.LessOrEqual(Math.Abs(45 - otherSideNetworkTransform.transform.rotation.eulerAngles.x), approximation, $"wrong rotation on ghost on x, got {otherSideNetworkTransform.transform.rotation.eulerAngles.x}"); + //Assert.LessOrEqual(Math.Abs(40 - otherSideNetworkTransform.transform.rotation.eulerAngles.y), approximation, $"wrong rotation on ghost on y, got {otherSideNetworkTransform.transform.rotation.eulerAngles.y}"); + //Assert.LessOrEqual(Math.Abs(35 - otherSideNetworkTransform.transform.rotation.eulerAngles.z), approximation, $"wrong rotation on ghost on z, got {otherSideNetworkTransform.transform.rotation.eulerAngles.z}"); // test scale - UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.x, "wrong initial value for scale"); // sanity check - UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.y, "wrong initial value for scale"); // sanity check - UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.z, "wrong initial value for scale"); // sanity check + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.x, "wrong initial value for scale"); // sanity check + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.y, "wrong initial value for scale"); // sanity check + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(1f, otherSideNetworkTransform.transform.lossyScale.z, "wrong initial value for scale"); // sanity check authPlayerTransform.localScale = new Vector3(2, 3, 4); - yield return WaitForConditionOrTimeOut(() => otherSideNetworkTransform.transform.lossyScale.x > 1f + approximation); + yield return WaitForConditionOrTimeOut(ServerClientScaleMatches); - Assert.False(s_GlobalTimeoutHelper.TimedOut, "timeout while waiting for scale change"); + AssertOnTimeout("timeout while waiting for scale change"); - UnityEngine.Assertions.Assert.AreApproximatelyEqual(2f, otherSideNetworkTransform.transform.lossyScale.x, "wrong scale on ghost"); - UnityEngine.Assertions.Assert.AreApproximatelyEqual(3f, otherSideNetworkTransform.transform.lossyScale.y, "wrong scale on ghost"); - UnityEngine.Assertions.Assert.AreApproximatelyEqual(4f, otherSideNetworkTransform.transform.lossyScale.z, "wrong scale on ghost"); + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(2f, otherSideNetworkTransform.transform.lossyScale.x, "wrong scale on ghost"); + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(3f, otherSideNetworkTransform.transform.lossyScale.y, "wrong scale on ghost"); + //UnityEngine.Assertions.Assert.AreApproximatelyEqual(4f, otherSideNetworkTransform.transform.lossyScale.z, "wrong scale on ghost"); // todo reparent and test // todo test all public API @@ -251,6 +251,82 @@ public IEnumerator TestRotationThresholdDeltaCheck() Assert.IsTrue(results.isRotationDirty, $"Rotation was not dirty when rotated by {Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!"); } + /// + /// + [UnityTest] + public IEnumerator TestBitsetValue() + { + // Get the client player's NetworkTransform for both instances + var authoritativeNetworkTransform = m_ServerSideClientPlayer.GetComponent(); + var otherSideNetworkTransform = m_ClientSideClientPlayer.GetComponent(); + otherSideNetworkTransform.RotAngleThreshold = authoritativeNetworkTransform.RotAngleThreshold = 0.1f; + yield return s_DefaultWaitForTick; + + authoritativeNetworkTransform.Interpolate = true; + otherSideNetworkTransform.Interpolate = true; + + yield return s_DefaultWaitForTick; + + authoritativeNetworkTransform.transform.rotation = Quaternion.Euler(1, 2, 3); + var serverLastSentState = authoritativeNetworkTransform.GetLastSentState(); + var clientReplicatedState = otherSideNetworkTransform.GetReplicatedNetworkState().Value; + yield return WaitForConditionOrTimeOut(() => clientReplicatedState.Bitset.Equals(serverLastSentState.Bitset)); + AssertOnTimeout($"Server-side sent state Bitset {serverLastSentState.Bitset} != Client-side replicated state Bitset {clientReplicatedState.Bitset}"); + + yield return WaitForConditionOrTimeOut(ServerClientRotationMatches); + AssertOnTimeout($"[Timed-Out] Server-side client rotation {m_ServerSideClientPlayer.transform.rotation.eulerAngles} != Client-side client rotation {m_ClientSideClientPlayer.transform.rotation.eulerAngles}"); + } + + private bool Aproximately(float x, float y) + { + return Mathf.Abs(x - y) <= k_AproximateDeltaVariance; + } + + private const float k_AproximateDeltaVariance = 0.01f; + + private bool ServerClientRotationMatches() + { + var serverEulerRotation = m_ServerSideClientPlayer.transform.rotation.eulerAngles; + var clientEulerRotation = m_ClientSideClientPlayer.transform.rotation.eulerAngles; + var xIsEqual = Aproximately(serverEulerRotation.x, clientEulerRotation.x); + var yIsEqual = Aproximately(serverEulerRotation.y, clientEulerRotation.y); + var zIsEqual = Aproximately(serverEulerRotation.z, clientEulerRotation.z); + if (!xIsEqual || !yIsEqual || !zIsEqual) + { + VerboseDebug($"Server-side client rotation {m_ServerSideClientPlayer.transform.rotation.eulerAngles} != Client-side client rotation {m_ClientSideClientPlayer.transform.rotation.eulerAngles}"); + } + return xIsEqual && yIsEqual && zIsEqual; + } + + private bool ServerClientPositionMatches() + { + var serverPosition = m_ServerSideClientPlayer.transform.position; + var clientPosition = m_ClientSideClientPlayer.transform.position; + var xIsEqual = Aproximately(serverPosition.x, clientPosition.x); + var yIsEqual = Aproximately(serverPosition.y, clientPosition.y); + var zIsEqual = Aproximately(serverPosition.z, clientPosition.z); + if (!xIsEqual || !yIsEqual || !zIsEqual) + { + VerboseDebug($"Server-side client position {m_ServerSideClientPlayer.transform.position} != Client-side client position {m_ClientSideClientPlayer.transform.position}"); + } + return xIsEqual && yIsEqual && zIsEqual; + } + + private bool ServerClientScaleMatches() + { + var serverScale = m_ServerSideClientPlayer.transform.localScale; + var clientScale = m_ClientSideClientPlayer.transform.localScale; + var xIsEqual = Aproximately(serverScale.x, clientScale.x); + var yIsEqual = Aproximately(serverScale.y, clientScale.y); + var zIsEqual = Aproximately(serverScale.z, clientScale.z); + if (!xIsEqual || !yIsEqual || !zIsEqual) + { + VerboseDebug($"Server-side client scale {m_ServerSideClientPlayer.transform.localScale} != Client-side client scale {m_ClientSideClientPlayer.transform.localScale}"); + } + return xIsEqual && yIsEqual && zIsEqual; + } + + /* * ownership change * test teleport with interpolation @@ -259,6 +335,7 @@ public IEnumerator TestRotationThresholdDeltaCheck() */ protected override IEnumerator OnTearDown() { + m_EnableVerboseDebug = false; UnityEngine.Object.DestroyImmediate(m_PlayerPrefab); yield return base.OnTearDown(); } From e09e0a03d5d29ef9f2d85f0aa6a0561ab8cb3cf2 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Thu, 4 Aug 2022 15:55:50 -0500 Subject: [PATCH 08/17] style removing an unused namespace. --- .../Tests/Runtime/NetworkTransform/NetworkTransformTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index 0f6590a657..313866e58d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; #if NGO_TRANSFORM_DEBUG using System.Text.RegularExpressions; From 7a2bdb3d33c8bf9adf3fa84d0861c91999aaa571 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Thu, 4 Aug 2022 16:54:59 -0500 Subject: [PATCH 09/17] style fixing issue with reference to UnityEngine's Object after I removed the system namespace. --- .../Tests/Runtime/NetworkTransform/NetworkTransformTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index 313866e58d..14c10862ed 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -335,7 +335,7 @@ private bool ServerClientScaleMatches() protected override IEnumerator OnTearDown() { m_EnableVerboseDebug = false; - UnityEngine.Object.DestroyImmediate(m_PlayerPrefab); + Object.DestroyImmediate(m_PlayerPrefab); yield return base.OnTearDown(); } } From ba114f7468e1bf0d9fb2052689166e59b1b83746 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 08:51:21 -0500 Subject: [PATCH 10/17] fix This includes the adjustments for client authoritative mode to work without sending RPCs. --- .../Components/NetworkTransform.cs | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 458b109004..ed612b1246 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -366,11 +366,18 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade /// protected NetworkManager m_CachedNetworkManager; - private readonly NetworkVariable m_ReplicatedNetworkState = new NetworkVariable(new NetworkTransformState()); + private readonly NetworkVariable m_ReplicatedNetworkStateServer = new NetworkVariable(new NetworkTransformState(), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); + private readonly NetworkVariable m_ReplicatedNetworkStateOwner = new NetworkVariable(new NetworkTransformState(), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); + internal NetworkVariable GetReplicatedNetworkState() { - return m_ReplicatedNetworkState; + if (!IsServerAuthoritative()) + { + return m_ReplicatedNetworkStateOwner; + } + + return m_ReplicatedNetworkStateServer; } private NetworkTransformState m_LocalAuthoritativeNetworkState; @@ -422,7 +429,7 @@ private void TryCommit(bool isDirty) { void Send(NetworkTransformState stateToSend) { - if (m_CachedIsServer) + if (CanCommitToTransform) { // server RPC takes a few frames to execute server side, we want this to execute immediately CommitLocallyAndReplicate(stateToSend); @@ -466,7 +473,7 @@ private void CommitTransformServerRpc(NetworkTransformState networkState, Server private void CommitLocallyAndReplicate(NetworkTransformState networkState) { - m_ReplicatedNetworkState.Value = networkState; + GetReplicatedNetworkState().Value = networkState; if (Interpolate) { @@ -974,19 +981,21 @@ private void SetTransformValues() /// public override void OnNetworkSpawn() { + CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner; + // must set up m_Transform in OnNetworkSpawn because it's possible an object spawns but is disabled // and thus awake won't be called. // TODO: investigate further on not sending data for something that is not enabled m_Transform = transform; - m_ReplicatedNetworkState.OnValueChanged += OnNetworkStateChanged; + GetReplicatedNetworkState().OnValueChanged += OnNetworkStateChanged; - CanCommitToTransform = IsServer; m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; - m_LocalAuthoritativeNetworkState = m_ReplicatedNetworkState.Value; + m_LocalAuthoritativeNetworkState = GetReplicatedNetworkState().Value; if (CanCommitToTransform) { + m_LastSentState = GetReplicatedNetworkState().Value; TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } else @@ -1003,7 +1012,7 @@ public override void OnNetworkSpawn() /// public override void OnNetworkDespawn() { - m_ReplicatedNetworkState.OnValueChanged -= OnNetworkStateChanged; + GetReplicatedNetworkState().OnValueChanged -= OnNetworkStateChanged; } /// @@ -1024,11 +1033,11 @@ private void Initialize() if (CanCommitToTransform) { - m_ReplicatedNetworkState.SetDirty(true); + GetReplicatedNetworkState().SetDirty(true); } else if (m_Transform != null) { - ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform, NetworkManager.ServerTime.Time); + ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, NetworkManager.ServerTime.Time); } } @@ -1114,10 +1123,7 @@ protected virtual void Update() if (CanCommitToTransform) { - if (m_CachedIsServer) - { - TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); - } + TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } else { @@ -1150,7 +1156,7 @@ protected virtual void Update() ApplyTransformValues(); // Apply updated interpolated value - ApplyInterpolatedNetworkStateToTransform(m_ReplicatedNetworkState.Value, m_Transform, serverTime.Time); + ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, serverTime.Time); // Always set the any new transform values to assure only the authoritative side is updating the transform SetTransformValues(); From e84cd5cd9bab5a30ab1c39f2087c867aeec96306 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 09:51:22 -0500 Subject: [PATCH 11/17] fix This update fixes the issue where the authoritative side was interpolating when interpolate is enabled. Now, the authoritative side no longer interpolates. --- .../Components/NetworkTransform.cs | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index ed612b1246..81a4311133 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -474,11 +474,6 @@ private void CommitTransformServerRpc(NetworkTransformState networkState, Server private void CommitLocallyAndReplicate(NetworkTransformState networkState) { GetReplicatedNetworkState().Value = networkState; - - if (Interpolate) - { - AddInterpolatedState(networkState); - } } private void ResetInterpolatedStateToCurrentAuthoritativeState() @@ -981,18 +976,18 @@ private void SetTransformValues() /// public override void OnNetworkSpawn() { + m_CachedIsServer = IsServer; + m_CachedNetworkManager = NetworkManager; + CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner; // must set up m_Transform in OnNetworkSpawn because it's possible an object spawns but is disabled // and thus awake won't be called. // TODO: investigate further on not sending data for something that is not enabled m_Transform = transform; - GetReplicatedNetworkState().OnValueChanged += OnNetworkStateChanged; - - m_CachedIsServer = IsServer; - m_CachedNetworkManager = NetworkManager; m_LocalAuthoritativeNetworkState = GetReplicatedNetworkState().Value; + if (CanCommitToTransform) { m_LastSentState = GetReplicatedNetworkState().Value; @@ -1000,6 +995,7 @@ public override void OnNetworkSpawn() } else { + GetReplicatedNetworkState().OnValueChanged += OnNetworkStateChanged; // For the non-authoritative side, we need to capture these values SetTransformValues(); } @@ -1029,14 +1025,13 @@ public override void OnLostOwnership() private void Initialize() { - ResetInterpolatedStateToCurrentAuthoritativeState(); // useful for late joining - if (CanCommitToTransform) { GetReplicatedNetworkState().SetDirty(true); } else if (m_Transform != null) { + ResetInterpolatedStateToCurrentAuthoritativeState(); // useful for late joining ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, NetworkManager.ServerTime.Time); } } @@ -1110,29 +1105,23 @@ protected virtual void Update() return; } - if (!Interpolate && m_LastInterpolate) - { - // if we just stopped interpolating, let's clear the interpolators - foreach (var interpolator in m_AllFloatInterpolators) - { - interpolator.Clear(); - } - } - - m_LastInterpolate = Interpolate; - if (CanCommitToTransform) { TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); } else { - ApplyTransformValues(); - } + if (!Interpolate && m_LastInterpolate) + { + // if we just stopped interpolating, let's clear the interpolators + foreach (var interpolator in m_AllFloatInterpolators) + { + interpolator.Clear(); + } + } + + m_LastInterpolate = Interpolate; - // apply interpolated value - if (m_CachedNetworkManager.IsConnectedClient || m_CachedNetworkManager.IsListening) - { // eventually, we could hoist this calculation so that it happens once for all objects, not once per object var cachedDeltaTime = Time.deltaTime; var serverTime = NetworkManager.ServerTime; @@ -1149,19 +1138,17 @@ protected virtual void Update() m_RotationInterpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime); } - if (!CanCommitToTransform) - { - // Always update from the last transform values before updating from the transform state to assure - // no non-authoritative changes are allowed - ApplyTransformValues(); + // Always update from the last transform values before updating from the transform state to assure + // no non-authoritative changes are allowed + ApplyTransformValues(); - // Apply updated interpolated value - ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, serverTime.Time); + // Apply updated interpolated value + ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, serverTime.Time); - // Always set the any new transform values to assure only the authoritative side is updating the transform - SetTransformValues(); - } + // Always set the any new transform values to assure only the authoritative side is updating the transform + SetTransformValues(); } + m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = false; } @@ -1185,7 +1172,7 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca stateToSend.Position = newPosition; stateToSend.Rotation = newRotationEuler; stateToSend.Scale = newScale; - ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); + //ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); // set teleport flag in state to signal to ghosts not to interpolate m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = true; // check server side From 08f1ef41f5c2de7b00593b46fef89ffda8973847 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 09:57:34 -0500 Subject: [PATCH 12/17] manual test updates These changes make the player client authoritative within the Samples Menu->Additive Scene Loading manual test/sample. --- .../ClientNetworkTransform.cs | 12 + .../ClientNetworkTransform.cs.meta | 11 + .../PlayerClientAuthoritative.prefab | 297 ++++++++++++++++++ .../PlayerClientAuthoritative.prefab.meta | 7 + .../SceneTransitioningBase1.unity | 2 +- .../Manual/Scripts/PlayerMovementManager.cs | 22 +- .../Tests/Manual/Scripts/RandomMovement.cs | 45 ++- 7 files changed, 373 insertions(+), 23 deletions(-) create mode 100644 testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs create mode 100644 testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs.meta create mode 100644 testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab create mode 100644 testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab.meta diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs new file mode 100644 index 0000000000..f236eac9bf --- /dev/null +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs @@ -0,0 +1,12 @@ +using Unity.Netcode.Components; + +namespace TestProject.ManualTests +{ + public class ClientNetworkTransform : NetworkTransform + { + protected override bool OnIsServerAuthoritative() + { + return false; + } + } +} diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs.meta b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs.meta new file mode 100644 index 0000000000..1c86c33058 --- /dev/null +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/ClientNetworkTransform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf01cca54b77c0241ad6d9da5ef6a709 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab new file mode 100644 index 0000000000..5fe8f7e1d0 --- /dev/null +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab @@ -0,0 +1,297 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &4079352819444256614 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4079352819444256611} + - component: {fileID: 972770265172480408} + - component: {fileID: -3775814466963834669} + - component: {fileID: 4079352819444256610} + - component: {fileID: 4079352819444256613} + - component: {fileID: 4079352819444256612} + - component: {fileID: 1750810845806302260} + - component: {fileID: 4053684789567975459} + - component: {fileID: 6442518961346739709} + - component: {fileID: 2756533617708860847} + - component: {fileID: 9187250582412873179} + m_Layer: 8 + m_Name: PlayerClientAuthoritative + m_TagString: Player + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4079352819444256611 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 5, y: 0.625, z: 5} + m_LocalScale: {x: 1.25, y: 1.25, z: 1.25} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3519470446676406143} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &972770265172480408 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: cf01cca54b77c0241ad6d9da5ef6a709, type: 3} + m_Name: + m_EditorClassIdentifier: + SyncPositionX: 1 + SyncPositionY: 1 + SyncPositionZ: 1 + SyncRotAngleX: 1 + SyncRotAngleY: 1 + SyncRotAngleZ: 1 + SyncScaleX: 1 + SyncScaleY: 1 + SyncScaleZ: 1 + PositionThreshold: 0.01 + RotAngleThreshold: 0.01 + ScaleThreshold: 0.01 + InLocalSpace: 0 + Interpolate: 1 +--- !u!114 &-3775814466963834669 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 951099334 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!33 &4079352819444256610 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &4079352819444256613 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a7b755ad8e4fe4bdb8f5518c951abc70, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &4079352819444256612 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!54 &1750810845806302260 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + serializedVersion: 2 + m_Mass: 100 + m_Drag: 7 + m_AngularDrag: 0.05 + m_UseGravity: 1 + m_IsKinematic: 0 + m_Interpolate: 1 + m_Constraints: 112 + m_CollisionDetection: 1 +--- !u!114 &4053684789567975459 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 24a9235f10bc6456183432fdb3015157, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &6442518961346739709 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e3e4ecffca0894dfa88af779c2a67b9e, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &2756533617708860847 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8e5aa2f75493a4fee8ec635d215f03c2, type: 3} + m_Name: + m_EditorClassIdentifier: + MoveSpeed: 10 +--- !u!114 &9187250582412873179 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079352819444256614} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f6c0be61502bb534f922ebb746851216, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &6479012615216050269 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3519470446676406143} + - component: {fileID: 6858102498835906389} + - component: {fileID: 2780619303711114328} + m_Layer: 8 + m_Name: PlayerSub + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3519470446676406143 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6479012615216050269} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.045, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4079352819444256611} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &6858102498835906389 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6479012615216050269} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &2780619303711114328 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6479012615216050269} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab.meta b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab.meta new file mode 100644 index 0000000000..3b1a7f37fd --- /dev/null +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/PlayerClientAuthoritative.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3cc5d500f7b2e1245bfb8652adadb286 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity index fb56264016..be71473fbe 100644 --- a/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity +++ b/testproject/Assets/Tests/Manual/SceneTransitioningAdditive/SceneTransitioningBase1.unity @@ -2342,7 +2342,7 @@ MonoBehaviour: NetworkConfig: ProtocolVersion: 0 NetworkTransport: {fileID: 1024114723} - PlayerPrefab: {fileID: 4079352819444256614, guid: c16f03336b6104576a565ef79ad643c0, + PlayerPrefab: {fileID: 4079352819444256614, guid: 3cc5d500f7b2e1245bfb8652adadb286, type: 3} NetworkPrefabs: - Override: 0 diff --git a/testproject/Assets/Tests/Manual/Scripts/PlayerMovementManager.cs b/testproject/Assets/Tests/Manual/Scripts/PlayerMovementManager.cs index 763ef5819e..b8c0ae786b 100644 --- a/testproject/Assets/Tests/Manual/Scripts/PlayerMovementManager.cs +++ b/testproject/Assets/Tests/Manual/Scripts/PlayerMovementManager.cs @@ -20,22 +20,20 @@ private void Start() private void Update() { - if (NetworkObject != null) + if (!IsSpawned) { - if (IsOwner && Input.GetKeyDown(KeyCode.Space)) + return; + } + + if (IsOwner) + { + if (Input.GetKeyDown(KeyCode.Space)) { - if (m_RandomMovement) - { - m_RandomMovement.enabled = !m_RandomMovement.enabled; - } + m_RandomMovement.enabled = !m_RandomMovement.enabled; } - - if (NetworkObject != null && NetworkObject.NetworkManager != null && NetworkObject.NetworkManager.IsListening) + if (m_RandomMovement.enabled) { - if (m_RandomMovement.enabled) - { - m_RandomMovement.Move(MoveSpeed); - } + m_RandomMovement.Move(MoveSpeed); } } } diff --git a/testproject/Assets/Tests/Manual/Scripts/RandomMovement.cs b/testproject/Assets/Tests/Manual/Scripts/RandomMovement.cs index 6aa161ceb0..846d64aa4c 100644 --- a/testproject/Assets/Tests/Manual/Scripts/RandomMovement.cs +++ b/testproject/Assets/Tests/Manual/Scripts/RandomMovement.cs @@ -1,5 +1,6 @@ using UnityEngine; using Unity.Netcode; +using Unity.Netcode.Components; namespace TestProject.ManualTests { @@ -12,13 +13,33 @@ public class RandomMovement : NetworkBehaviour, IPlayerMovement private Vector3 m_Direction; private Rigidbody m_Rigidbody; + private NetworkTransform m_NetworkTransform; + private ClientNetworkTransform m_ClientNetworkTransform; + + private bool HasAuthority() + { + if (m_NetworkTransform != null) + { + if (m_ClientNetworkTransform == null) + { + m_ClientNetworkTransform = m_NetworkTransform as ClientNetworkTransform; + } + if (m_ClientNetworkTransform != null) + { + return IsOwner; + } + } + + return IsServer; + } public override void OnNetworkSpawn() { m_Rigidbody = GetComponent(); + m_NetworkTransform = GetComponent(); if (NetworkObject != null && m_Rigidbody != null) { - if (NetworkObject.IsOwner) + if (m_NetworkTransform.NetworkObject.IsOwner) { ChangeDirection(true, true); } @@ -40,18 +61,18 @@ private void MovePlayerServerRpc(Vector3 moveTowards) public void Move(int speed) { // Server sets this locally - if (IsServer && IsOwner) + if (HasAuthority()) { m_MoveTowardsPosition = (m_Direction * speed); } - else if (!IsServer && IsOwner) + else if (m_ClientNetworkTransform == null && !IsServer && IsOwner) { // Client must sent Rpc MovePlayerServerRpc(m_Direction * speed * 1.05f); - } - else if (IsServer && !IsOwner) - { - m_MoveTowardsPosition = Vector3.Lerp(m_MoveTowardsPosition, Vector3.zero, 0.01f); + if (IsServer && !IsOwner) + { + m_MoveTowardsPosition = Vector3.Lerp(m_MoveTowardsPosition, Vector3.zero, 0.01f); + } } } @@ -59,7 +80,11 @@ public void Move(int speed) // We just apply our current direction with magnitude to our current position during fixed update private void FixedUpdate() { - if (IsServer && NetworkObject && NetworkObject.NetworkManager && NetworkObject.NetworkManager.IsListening) + if (!IsSpawned) + { + return; + } + if (HasAuthority()) { if (m_Rigidbody == null) { @@ -84,7 +109,7 @@ private void ChangeDirectionClientRpc(Vector3 direction) private void OnCollisionStay(Collision collision) { - if (IsServer) + if (HasAuthority()) { if (collision.gameObject.CompareTag("Floor") || collision.gameObject.CompareTag("GenericObject")) { @@ -98,7 +123,7 @@ private void OnCollisionStay(Collision collision) // If we are not the owner then we need to notify the client that their direction // must change - if (!IsOwner) + if (m_ClientNetworkTransform == null && IsServer && !IsOwner) { m_MoveTowardsPosition = m_Direction * m_MoveTowardsPosition.magnitude; ChangeDirectionClientRpc(m_Direction); From b15ce6ad90a8c843be762ba6dd79af71cf5e9d7a Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 13:41:17 -0500 Subject: [PATCH 13/17] update reverting the change of m_Bitset to an internal. --- .../Components/NetworkTransform.cs | 148 ++++++++++-------- 1 file changed, 80 insertions(+), 68 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 81a4311133..f5ff12c867 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -60,120 +60,120 @@ internal struct NetworkTransformState : INetworkSerializable private const int k_ScaleYBit = 8; private const int k_ScaleZBit = 9; private const int k_TeleportingBit = 10; - // 11-15: - internal ushort Bitset; + + private ushort m_Bitset; internal bool InLocalSpace { - get => (Bitset & (1 << k_InLocalSpaceBit)) != 0; + get => (m_Bitset & (1 << k_InLocalSpaceBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_InLocalSpaceBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_InLocalSpaceBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_InLocalSpaceBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_InLocalSpaceBit)); } } } // Position internal bool HasPositionX { - get => (Bitset & (1 << k_PositionXBit)) != 0; + get => (m_Bitset & (1 << k_PositionXBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionXBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_PositionXBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionXBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionXBit)); } } } internal bool HasPositionY { - get => (Bitset & (1 << k_PositionYBit)) != 0; + get => (m_Bitset & (1 << k_PositionYBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionYBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_PositionYBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionYBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionYBit)); } } } internal bool HasPositionZ { - get => (Bitset & (1 << k_PositionZBit)) != 0; + get => (m_Bitset & (1 << k_PositionZBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_PositionZBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_PositionZBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_PositionZBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_PositionZBit)); } } } // RotAngles internal bool HasRotAngleX { - get => (Bitset & (1 << k_RotAngleXBit)) != 0; + get => (m_Bitset & (1 << k_RotAngleXBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleXBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleXBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleXBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleXBit)); } } } internal bool HasRotAngleY { - get => (Bitset & (1 << k_RotAngleYBit)) != 0; + get => (m_Bitset & (1 << k_RotAngleYBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleYBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleYBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleYBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleYBit)); } } } internal bool HasRotAngleZ { - get => (Bitset & (1 << k_RotAngleZBit)) != 0; + get => (m_Bitset & (1 << k_RotAngleZBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_RotAngleZBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_RotAngleZBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_RotAngleZBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_RotAngleZBit)); } } } // Scale internal bool HasScaleX { - get => (Bitset & (1 << k_ScaleXBit)) != 0; + get => (m_Bitset & (1 << k_ScaleXBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleXBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleXBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleXBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleXBit)); } } } internal bool HasScaleY { - get => (Bitset & (1 << k_ScaleYBit)) != 0; + get => (m_Bitset & (1 << k_ScaleYBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleYBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleYBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleYBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleYBit)); } } } internal bool HasScaleZ { - get => (Bitset & (1 << k_ScaleZBit)) != 0; + get => (m_Bitset & (1 << k_ScaleZBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_ScaleZBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_ScaleZBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_ScaleZBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_ScaleZBit)); } } } internal bool IsTeleportingNextFrame { - get => (Bitset & (1 << k_TeleportingBit)) != 0; + get => (m_Bitset & (1 << k_TeleportingBit)) != 0; set { - if (value) { Bitset = (ushort)(Bitset | (1 << k_TeleportingBit)); } - else { Bitset = (ushort)(Bitset & ~(1 << k_TeleportingBit)); } + if (value) { m_Bitset = (ushort)(m_Bitset | (1 << k_TeleportingBit)); } + else { m_Bitset = (ushort)(m_Bitset & ~(1 << k_TeleportingBit)); } } } @@ -219,7 +219,7 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade { serializer.SerializeValue(ref SentTime); // InLocalSpace + HasXXX Bits - serializer.SerializeValue(ref Bitset); + serializer.SerializeValue(ref m_Bitset); // Position Values if (HasPositionX) { @@ -414,11 +414,22 @@ internal NetworkTransformState GetLastSentState() /// protected void TryCommitTransformToServer(Transform transformToCommit, double dirtyTime) { + TryCommitTransform(transformToCommit, dirtyTime); + } + + + protected void TryCommitTransform(Transform transformToCommit, double dirtyTime) + { + if (!CanCommitToTransform) + { + Debug.LogError($"[{name}] is trying to commit the transform without authority!"); + return; + } var isDirty = ApplyTransformToNetworkState(ref m_LocalAuthoritativeNetworkState, dirtyTime, transformToCommit); TryCommit(isDirty); } - private void TryCommitValuesToServer(Vector3 position, Vector3 rotation, Vector3 scale, double dirtyTime) + private void TryCommitValues(Vector3 position, Vector3 rotation, Vector3 scale, double dirtyTime) { var isDirty = ApplyTransformToNetworkStateWithInfo(ref m_LocalAuthoritativeNetworkState, dirtyTime, position, rotation, scale); @@ -979,26 +990,6 @@ public override void OnNetworkSpawn() m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; - CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner; - - // must set up m_Transform in OnNetworkSpawn because it's possible an object spawns but is disabled - // and thus awake won't be called. - // TODO: investigate further on not sending data for something that is not enabled - m_Transform = transform; - - m_LocalAuthoritativeNetworkState = GetReplicatedNetworkState().Value; - - if (CanCommitToTransform) - { - m_LastSentState = GetReplicatedNetworkState().Value; - TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); - } - else - { - GetReplicatedNetworkState().OnValueChanged += OnNetworkStateChanged; - // For the non-authoritative side, we need to capture these values - SetTransformValues(); - } // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object @@ -1025,14 +1016,35 @@ public override void OnLostOwnership() private void Initialize() { + if (!IsSpawned) + { + return; + } + + // must set up m_Transform in OnNetworkSpawn because it's possible an object spawns but is disabled + // and thus awake won't be called. + // TODO: investigate further on not sending data for something that is not enabled + m_Transform = transform; + + CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner; + var replicatedState = GetReplicatedNetworkState(); + m_LocalAuthoritativeNetworkState = replicatedState.Value; + if (CanCommitToTransform) { - GetReplicatedNetworkState().SetDirty(true); + GetReplicatedNetworkState().OnValueChanged -= OnNetworkStateChanged; + TryCommitTransform(m_Transform, m_CachedNetworkManager.LocalTime.Time); + replicatedState.SetDirty(true); } - else if (m_Transform != null) + else { + replicatedState.OnValueChanged += OnNetworkStateChanged; ResetInterpolatedStateToCurrentAuthoritativeState(); // useful for late joining - ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, NetworkManager.ServerTime.Time); + + // For the non-authoritative side, we need to capture these values + SetTransformValues(); + + ApplyInterpolatedNetworkStateToTransform(replicatedState.Value, m_Transform, NetworkManager.ServerTime.Time); } } @@ -1107,7 +1119,7 @@ protected virtual void Update() if (CanCommitToTransform) { - TryCommitTransformToServer(m_Transform, m_CachedNetworkManager.LocalTime.Time); + TryCommitTransform(m_Transform, m_CachedNetworkManager.LocalTime.Time); } else { @@ -1123,13 +1135,13 @@ protected virtual void Update() m_LastInterpolate = Interpolate; // eventually, we could hoist this calculation so that it happens once for all objects, not once per object - var cachedDeltaTime = Time.deltaTime; - var serverTime = NetworkManager.ServerTime; - var cachedServerTime = serverTime.Time; - var cachedRenderTime = serverTime.TimeTicksAgo(1).Time; + var serverTime = NetworkManager.ServerTime; if (Interpolate) { + var cachedDeltaTime = Time.deltaTime; + var cachedServerTime = serverTime.Time; + var cachedRenderTime = serverTime.TimeTicksAgo(1).Time; foreach (var interpolator in m_AllFloatInterpolators) { interpolator.Update(cachedDeltaTime, cachedRenderTime, cachedServerTime); @@ -1172,11 +1184,11 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca stateToSend.Position = newPosition; stateToSend.Rotation = newRotationEuler; stateToSend.Scale = newScale; - //ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); + ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); // set teleport flag in state to signal to ghosts not to interpolate m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = true; - // check server side - TryCommitValuesToServer(newPosition, newRotationEuler, newScale, m_CachedNetworkManager.LocalTime.Time); + + TryCommitValues(newPosition, newRotationEuler, newScale, m_CachedNetworkManager.LocalTime.Time); m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = false; } From ef854bfad9d974791bb82ae1835f88f7d93c378f Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 13:41:47 -0500 Subject: [PATCH 14/17] test update updating test to account for reverting back to the private m_Bitset. --- .../NetworkTransform/NetworkTransformTests.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index 14c10862ed..a835ecef6b 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -250,6 +250,17 @@ public IEnumerator TestRotationThresholdDeltaCheck() Assert.IsTrue(results.isRotationDirty, $"Rotation was not dirty when rotated by {Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!"); } + private bool ValidateBitSetValues(NetworkTransform.NetworkTransformState serverState, NetworkTransform.NetworkTransformState clientState) + { + if (serverState.HasPositionX == clientState.HasPositionX && serverState.HasPositionY == clientState.HasPositionY && serverState.HasPositionZ == clientState.HasPositionZ && + serverState.HasRotAngleX == clientState.HasRotAngleX && serverState.HasRotAngleY == clientState.HasRotAngleY && serverState.HasRotAngleZ == clientState.HasRotAngleZ && + serverState.HasScaleX == clientState.HasScaleX && serverState.HasScaleY == clientState.HasScaleY && serverState.HasScaleZ == clientState.HasScaleZ) + { + return true; + } + return false; + } + /// /// [UnityTest] @@ -269,8 +280,8 @@ public IEnumerator TestBitsetValue() authoritativeNetworkTransform.transform.rotation = Quaternion.Euler(1, 2, 3); var serverLastSentState = authoritativeNetworkTransform.GetLastSentState(); var clientReplicatedState = otherSideNetworkTransform.GetReplicatedNetworkState().Value; - yield return WaitForConditionOrTimeOut(() => clientReplicatedState.Bitset.Equals(serverLastSentState.Bitset)); - AssertOnTimeout($"Server-side sent state Bitset {serverLastSentState.Bitset} != Client-side replicated state Bitset {clientReplicatedState.Bitset}"); + yield return WaitForConditionOrTimeOut(() => ValidateBitSetValues(serverLastSentState, clientReplicatedState)); + AssertOnTimeout($"Server-side sent Bitset state != Client-side replicated Bitset state!"); yield return WaitForConditionOrTimeOut(ServerClientRotationMatches); AssertOnTimeout($"[Timed-Out] Server-side client rotation {m_ServerSideClientPlayer.transform.rotation.eulerAngles} != Client-side client rotation {m_ClientSideClientPlayer.transform.rotation.eulerAngles}"); From d2a68e18008b527d6dd0a4ac8e74d1283293fc10 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Fri, 5 Aug 2022 16:15:25 -0500 Subject: [PATCH 15/17] update Migrated the code that updates interpolators with the current value if the axis is not set into the AddInterpolatedState method as opposed to it being in the ApplyInterpolatedNetworkStateToTransform --- .../Components/NetworkTransform.cs | 114 +++++++++++------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index f5ff12c867..902fbebcb5 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -703,35 +703,24 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw // InLocalSpace Read InLocalSpace = networkState.InLocalSpace; - // Position Read + + // Update the position values that were changed in this state update if (networkState.HasPositionX) { interpolatedPosition.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.x : m_PositionXInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_PositionXInterpolator.AddMeasurement(interpolatedPosition.x, serverTime); - } if (networkState.HasPositionY) { interpolatedPosition.y = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.y : m_PositionYInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_PositionYInterpolator.AddMeasurement(interpolatedPosition.y, serverTime); - } if (networkState.HasPositionZ) { interpolatedPosition.z = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Position.z : m_PositionZInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_PositionZInterpolator.AddMeasurement(interpolatedPosition.z, serverTime); - } - // again, we should be using quats here + // Update the rotation values that were changed in this state update if (networkState.HasRotAngleX || networkState.HasRotAngleY || networkState.HasRotAngleZ) { var eulerAngles = new Vector3(); @@ -756,35 +745,23 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw } } - // Scale Read + // Update all scale axis that were changed in this state update if (networkState.HasScaleX) { interpolatedScale.x = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.x : m_ScaleXInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_ScaleXInterpolator.AddMeasurement(interpolatedScale.x, serverTime); - } if (networkState.HasScaleY) { interpolatedScale.y = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.y : m_ScaleYInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_ScaleYInterpolator.AddMeasurement(interpolatedScale.x, serverTime); - } if (networkState.HasScaleZ) { interpolatedScale.z = networkState.IsTeleportingNextFrame || !Interpolate ? networkState.Scale.z : m_ScaleZInterpolator.GetInterpolatedValue(); } - else if (Interpolate) - { - m_ScaleZInterpolator.AddMeasurement(interpolatedScale.x, serverTime); - } - // Position Apply + // Apply the new position if (networkState.HasPositionX || networkState.HasPositionY || networkState.HasPositionZ) { if (InLocalSpace) @@ -798,7 +775,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw } } - // RotAngles Apply + // Apply the new rotation if (networkState.HasRotAngleX || networkState.HasRotAngleY || networkState.HasRotAngleZ) { if (InLocalSpace) @@ -811,7 +788,7 @@ private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState netw } } - // Scale Apply + // Apply the new scale if (networkState.HasScaleX || networkState.HasScaleY || networkState.HasScaleZ) { transformToUpdate.localScale = interpolatedScale; @@ -858,40 +835,76 @@ private void AddInterpolatedState(NetworkTransformState newState, bool reset = f return; } + + var currentPosition = InLocalSpace ? m_Transform.localPosition : m_Transform.position; + + // Note: Any values we don't have an update for need their interpolator deltas reset. + // Bandwidth optimizations mean that an update without the value set indicates "this hasn't changed", + // and so we need to tell the interpolators that it's the last currently known axis value(s) at this + // time delta. + if (newState.HasPositionX) { m_PositionXInterpolator.AddMeasurement(newState.PositionX, sentTime); } + else + { + m_PositionXInterpolator.AddMeasurement(m_LastStatePosition.x, sentTime); + } if (newState.HasPositionY) { m_PositionYInterpolator.AddMeasurement(newState.PositionY, sentTime); } + else + { + m_PositionYInterpolator.AddMeasurement(m_LastStatePosition.y, sentTime); + } if (newState.HasPositionZ) { m_PositionZInterpolator.AddMeasurement(newState.PositionZ, sentTime); } + else + { + m_PositionZInterpolator.AddMeasurement(m_LastStatePosition.z, sentTime); + } if (newState.HasRotAngleX || newState.HasRotAngleY || newState.HasRotAngleZ) { m_RotationInterpolator.AddMeasurement(Quaternion.Euler(newState.Rotation), sentTime); } + else + { + m_RotationInterpolator.AddMeasurement(m_LastStateRotation, sentTime); + } if (newState.HasScaleX) { m_ScaleXInterpolator.AddMeasurement(newState.ScaleX, sentTime); } + else + { + m_ScaleXInterpolator.AddMeasurement(m_LocalScale.x, sentTime); + } if (newState.HasScaleY) { m_ScaleYInterpolator.AddMeasurement(newState.ScaleY, sentTime); } + else + { + m_ScaleYInterpolator.AddMeasurement(m_LocalScale.y, sentTime); + } if (newState.HasScaleZ) { m_ScaleZInterpolator.AddMeasurement(newState.ScaleZ, sentTime); } + else + { + m_ScaleZInterpolator.AddMeasurement(m_LocalScale.z, sentTime); + } } private void OnNetworkStateChanged(NetworkTransformState oldState, NetworkTransformState newState) @@ -960,18 +973,34 @@ private void Awake() /// This prevents non-authoritative instances from changing /// the transform. /// - private Vector3 m_LocalPosition; + private Vector3 m_LastStatePosition; private Vector3 m_LocalScale; - private Quaternion m_LocalRotation; + private Quaternion m_LastStateRotation; /// /// Applies the last authorized position, scale, and rotation /// private void ApplyTransformValues() { - m_Transform.position = m_LocalPosition; + if (InLocalSpace) + { + m_Transform.localPosition = m_LastStatePosition; + } + else + { + m_Transform.position = m_LastStatePosition; + } + + if (InLocalSpace) + { + m_Transform.localRotation = m_LastStateRotation; + } + else + { + m_Transform.rotation = m_LastStateRotation; + } + m_Transform.localScale = m_LocalScale; - m_Transform.rotation = m_LocalRotation; } /// @@ -979,9 +1008,9 @@ private void ApplyTransformValues() /// private void SetTransformValues() { - m_LocalPosition = m_Transform.position; + m_LastStatePosition = InLocalSpace ? m_Transform.localPosition : m_Transform.position; + m_LastStateRotation = InLocalSpace ? m_Transform.localRotation : m_Transform.rotation; m_LocalScale = m_Transform.localScale; - m_LocalRotation = m_Transform.rotation; } /// @@ -990,7 +1019,6 @@ public override void OnNetworkSpawn() m_CachedIsServer = IsServer; m_CachedNetworkManager = NetworkManager; - // crucial we do this to reset the interpolators so that recycled objects when using a pool will // not have leftover interpolator state from the previous object Initialize(); @@ -1039,12 +1067,12 @@ private void Initialize() else { replicatedState.OnValueChanged += OnNetworkStateChanged; - ResetInterpolatedStateToCurrentAuthoritativeState(); // useful for late joining - // For the non-authoritative side, we need to capture these values - SetTransformValues(); + // In case we are late joining + ResetInterpolatedStateToCurrentAuthoritativeState(); - ApplyInterpolatedNetworkStateToTransform(replicatedState.Value, m_Transform, NetworkManager.ServerTime.Time); + // For the non-authoritative side, we need to capture the initial values of the transform + SetTransformValues(); } } @@ -1165,7 +1193,7 @@ protected virtual void Update() } /// - /// Teleports the transform to the given values without interpolating + /// Teleport the transform to the given values without interpolating /// /// new position to move to. /// new rotation to rotate to. @@ -1184,7 +1212,7 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca stateToSend.Position = newPosition; stateToSend.Rotation = newRotationEuler; stateToSend.Scale = newScale; - ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); + //ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); // set teleport flag in state to signal to ghosts not to interpolate m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = true; From e0c91fd410e60283edb59e0141c20f05aa2e64d4 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Tue, 9 Aug 2022 09:14:01 -0500 Subject: [PATCH 16/17] update applying suggested changes --- .../Components/NetworkTransform.cs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 902fbebcb5..085d677283 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -406,23 +406,23 @@ internal NetworkTransformState GetLastSentState() } /// - /// Tries updating the server authoritative transform, only if allowed. - /// If this called server side, this will commit directly. - /// If no update is needed, nothing will be sent. This method should still be called every update, it'll self manage when it should and shouldn't send + /// Refer to , this is a legacy method. /// - /// - /// protected void TryCommitTransformToServer(Transform transformToCommit, double dirtyTime) { TryCommitTransform(transformToCommit, dirtyTime); } - + /// + /// Tries updating the server authoritative transform, only if allowed. + /// + /// the transform to be committed + /// time it was marked dirty protected void TryCommitTransform(Transform transformToCommit, double dirtyTime) { if (!CanCommitToTransform) { - Debug.LogError($"[{name}] is trying to commit the transform without authority!"); + NetworkLog.LogError($"[{name}] is trying to commit the transform without authority!"); return; } var isDirty = ApplyTransformToNetworkState(ref m_LocalAuthoritativeNetworkState, dirtyTime, transformToCommit); @@ -690,9 +690,6 @@ internal bool ApplyTransformToNetworkState(ref NetworkTransformState networkStat /// from having too large of a delta time between the time it was last updated and the time any new update is /// sent. /// - /// new state to apply - /// transform to update - /// required to interpolate when axis is not updated in the state to apply private void ApplyInterpolatedNetworkStateToTransform(NetworkTransformState networkState, Transform transformToUpdate, double serverTime) { var interpolatedPosition = InLocalSpace ? transformToUpdate.localPosition : transformToUpdate.position; @@ -1060,7 +1057,7 @@ private void Initialize() if (CanCommitToTransform) { - GetReplicatedNetworkState().OnValueChanged -= OnNetworkStateChanged; + replicatedState.OnValueChanged -= OnNetworkStateChanged; TryCommitTransform(m_Transform, m_CachedNetworkManager.LocalTime.Time); replicatedState.SetDirty(true); } @@ -1212,7 +1209,7 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca stateToSend.Position = newPosition; stateToSend.Rotation = newRotationEuler; stateToSend.Scale = newScale; - //ApplyInterpolatedNetworkStateToTransform(stateToSend, transform, m_CachedNetworkManager.ServerTime.Time); + // set teleport flag in state to signal to ghosts not to interpolate m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = true; From 6166469335872674263580cb9d2d9330a3982667 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity <73188597+NoelStephensUnity@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:37:37 -0500 Subject: [PATCH 17/17] update replacing the GetReplicatedNetworkState() method with a getter ReplicatedNetworkState property. --- .../Components/NetworkTransform.cs | 21 +++++++++++-------- .../NetworkTransform/NetworkTransformTests.cs | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index 085d677283..40d244168c 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -370,14 +370,17 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade private readonly NetworkVariable m_ReplicatedNetworkStateOwner = new NetworkVariable(new NetworkTransformState(), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); - internal NetworkVariable GetReplicatedNetworkState() + internal NetworkVariable ReplicatedNetworkState { - if (!IsServerAuthoritative()) + get { - return m_ReplicatedNetworkStateOwner; - } + if (!IsServerAuthoritative()) + { + return m_ReplicatedNetworkStateOwner; + } - return m_ReplicatedNetworkStateServer; + return m_ReplicatedNetworkStateServer; + } } private NetworkTransformState m_LocalAuthoritativeNetworkState; @@ -484,7 +487,7 @@ private void CommitTransformServerRpc(NetworkTransformState networkState, Server private void CommitLocallyAndReplicate(NetworkTransformState networkState) { - GetReplicatedNetworkState().Value = networkState; + ReplicatedNetworkState.Value = networkState; } private void ResetInterpolatedStateToCurrentAuthoritativeState() @@ -1024,7 +1027,7 @@ public override void OnNetworkSpawn() /// public override void OnNetworkDespawn() { - GetReplicatedNetworkState().OnValueChanged -= OnNetworkStateChanged; + ReplicatedNetworkState.OnValueChanged -= OnNetworkStateChanged; } /// @@ -1052,7 +1055,7 @@ private void Initialize() m_Transform = transform; CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner; - var replicatedState = GetReplicatedNetworkState(); + var replicatedState = ReplicatedNetworkState; m_LocalAuthoritativeNetworkState = replicatedState.Value; if (CanCommitToTransform) @@ -1180,7 +1183,7 @@ protected virtual void Update() ApplyTransformValues(); // Apply updated interpolated value - ApplyInterpolatedNetworkStateToTransform(GetReplicatedNetworkState().Value, m_Transform, serverTime.Time); + ApplyInterpolatedNetworkStateToTransform(ReplicatedNetworkState.Value, m_Transform, serverTime.Time); // Always set the any new transform values to assure only the authoritative side is updating the transform SetTransformValues(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs index a835ecef6b..d248d929c0 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformTests.cs @@ -279,7 +279,7 @@ public IEnumerator TestBitsetValue() authoritativeNetworkTransform.transform.rotation = Quaternion.Euler(1, 2, 3); var serverLastSentState = authoritativeNetworkTransform.GetLastSentState(); - var clientReplicatedState = otherSideNetworkTransform.GetReplicatedNetworkState().Value; + var clientReplicatedState = otherSideNetworkTransform.ReplicatedNetworkState.Value; yield return WaitForConditionOrTimeOut(() => ValidateBitSetValues(serverLastSentState, clientReplicatedState)); AssertOnTimeout($"Server-side sent Bitset state != Client-side replicated Bitset state!");