From 30d1fb3d56f56cb7a1c3dcdb0fcbf06730a2cae1 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 16 Apr 2025 16:57:15 -0500 Subject: [PATCH 1/7] fix First pass at fixing the issue where a server authority instance would lag behind when using the new interpolators. This was especially visible when the moving body completely stopped, all state updates were processed, and then shortly later it began to move again there would be a delay between the 1st state update and the rest of the pending state updates. --- .../Interpolator/BufferedLinearInterpolator.cs | 16 +++++----------- .../Runtime/Components/NetworkTransform.cs | 5 ++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs b/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs index f96bb55392..f5f2413ed2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs @@ -192,6 +192,8 @@ public void Reset(T currentValue) TimeToTargetValue = 0.0f; DeltaTime = 0.0f; m_CurrentDeltaTime = 0.0f; + MaxDeltaTime = 0.0f; + LastRemainingTime = 0.0f; } } @@ -292,13 +294,9 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double var potentialItemNeedsProcessing = false; // In the event there is nothing left in the queue (i.e. motion/change stopped), we still need to determine if the target has been reached. - if (!noStateSet && m_BufferQueue.Count == 0) + if (!noStateSet && !InterpolateState.TargetReached) { - if (!InterpolateState.TargetReached) - { - InterpolateState.TargetReached = IsApproximately(InterpolateState.CurrentValue, InterpolateState.Target.Value.Item, GetPrecision()); - } - return; + InterpolateState.TargetReached = IsApproximately(InterpolateState.CurrentValue, InterpolateState.Target.Value.Item, GetPrecision()); } // Continue to process any remaining state updates in the queue (if any) @@ -314,14 +312,10 @@ private void TryConsumeFromBuffer(double renderTime, double minDeltaTime, double if (!noStateSet) { potentialItemNeedsProcessing = ((potentialItem.TimeSent <= renderTime) && potentialItem.TimeSent > InterpolateState.Target.Value.TimeSent); - if (!InterpolateState.TargetReached) - { - InterpolateState.TargetReached = IsApproximately(InterpolateState.CurrentValue, InterpolateState.Target.Value.Item, GetPrecision()); - } } // If we haven't set a target or we have another item that needs processing. - if (noStateSet || potentialItemNeedsProcessing) + if ((noStateSet && (potentialItem.TimeSent <= renderTime)) || potentialItemNeedsProcessing) { if (m_BufferQueue.TryDequeue(out BufferedItem target)) { diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 10e95c6017..12b9cf08c5 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -4049,13 +4049,12 @@ public double GetPositionLastRemainingTime() } #endif - - // Non-Authority private void UpdateInterpolation() { AdjustForChangeInTransformSpace(); - var timeSystem = m_CachedNetworkManager.ServerTime; + // Select the time system relative to the type of NetworkManager instance. + var timeSystem = m_CachedNetworkManager.IsServer ? m_CachedNetworkManager.ServerTime : m_CachedNetworkManager.LocalTime; var currentTime = timeSystem.Time; #if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D var cachedDeltaTime = m_UseRigidbodyForMotion ? m_CachedNetworkManager.RealTimeProvider.FixedDeltaTime : m_CachedNetworkManager.RealTimeProvider.DeltaTime; From 1fb246ed2b0cc460f67fcc1dc3fde04a7cd2f9d1 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Thu, 17 Apr 2025 23:28:53 -0500 Subject: [PATCH 2/7] update adding changelog entry. --- com.unity.netcode.gameobjects/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 065f0a09ea..6a9a6c8f5c 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -13,6 +13,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed issue where the new interpolator types were blocking after the first consumption of a sequence of buffered state updates. (#3413) - Fixed issue where root level in-scene placed `NetworkObject`s would only allow the ownership permission to be no less than distributable or sessionowner. (#3407) ### Changed From cc3d4e66ae31b6a5fccda25dbcf6b272d2b42688 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 21 Apr 2025 11:00:52 -0500 Subject: [PATCH 3/7] fix This fixes the issue where an authority NetworkTransform instance could check for any changes to the transform more than once in a single frame if the frame time was greater than the tick frequency. --- .../Runtime/Components/NetworkTransform.cs | 40 ++++++++++++------- .../Runtime/Core/NetworkManager.cs | 13 ++++++ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 12b9cf08c5..ecdec58fcf 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -935,6 +935,12 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade #region PROPERTIES AND GENERAL METHODS + /// + /// Used on the authority side only. + /// This is the current network tick and is set within . + /// + internal static int CurrentTick; + /// /// Pertains to Owner Authority and Interpolation
/// When enabled (default), 1 additional tick is added to the total number of ticks used to calculate the tick latency ("ticks ago") as a time. @@ -1878,6 +1884,8 @@ private void TryCommitTransform(ref Transform transformToCommit, bool synchroniz // If the state was explicitly set, then update the network tick to match the locally calculate tick if (m_LocalAuthoritativeNetworkState.ExplicitSet) { + // For explicit set, we use the current ServerTime.Tick and not CurrentTick since this is a SetState specific flow + // that is outside of the normal internal tick flow. m_LocalAuthoritativeNetworkState.NetworkTick = m_CachedNetworkManager.NetworkTickSystem.ServerTime.Tick; } @@ -2011,7 +2019,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, ref Tra // send a full frame synch. var isAxisSync = false; // We compare against the NetworkTickSystem version since ServerTime is set when updating ticks - if (UseUnreliableDeltas && !isSynchronization && m_DeltaSynch && m_NextTickSync <= m_CachedNetworkManager.NetworkTickSystem.ServerTime.Tick) + if (UseUnreliableDeltas && !isSynchronization && m_DeltaSynch && m_NextTickSync <= CurrentTick) { // Increment to the next frame synch tick position for this instance m_NextTickSync += (int)m_CachedNetworkManager.NetworkConfig.TickRate; @@ -2179,7 +2187,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, ref Tra { // If we are teleporting then we can skip the delta threshold check isPositionDirty = networkState.IsTeleportingNextFrame || isAxisSync || forceState; - if (m_HalfFloatTargetTickOwnership > m_CachedNetworkManager.ServerTime.Tick) + if (m_HalfFloatTargetTickOwnership > CurrentTick) { isPositionDirty = true; } @@ -2225,7 +2233,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, ref Tra networkState.NetworkDeltaPosition = m_HalfPositionState; // If ownership offset is greater or we are doing an axial synchronization then synchronize the base position - if ((m_HalfFloatTargetTickOwnership > m_CachedNetworkManager.ServerTime.Tick || isAxisSync) && !networkState.IsTeleportingNextFrame) + if ((m_HalfFloatTargetTickOwnership > CurrentTick || isAxisSync) && !networkState.IsTeleportingNextFrame) { networkState.SynchronizeBaseHalfFloat = true; } @@ -2409,7 +2417,7 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, ref Tra if (enabled) { // We use the NetworkTickSystem version since ServerTime is set when updating ticks - networkState.NetworkTick = m_CachedNetworkManager.NetworkTickSystem.ServerTime.Tick; + networkState.NetworkTick = CurrentTick; } } @@ -2440,7 +2448,7 @@ private void OnNetworkTick(bool isCalledFromParent = false) } // If we are nested and have already sent a state update this tick, then exit early (otherwise check for any changes in state) - if (IsNested && m_LocalAuthoritativeNetworkState.NetworkTick == m_CachedNetworkManager.ServerTime.Tick) + if (IsNested && m_LocalAuthoritativeNetworkState.NetworkTick == CurrentTick) { return; } @@ -4500,6 +4508,15 @@ private void UpdateTransformState() #region NETWORK TICK REGISTRATOIN AND HANDLING private static Dictionary s_NetworkTickRegistration = new Dictionary(); + + internal static void UpdateNetworkTick(NetworkManager networkManager) + { + if (s_NetworkTickRegistration.ContainsKey(networkManager)) + { + s_NetworkTickRegistration[networkManager].TickUpdate(); + } + } + /// /// Adjusts the over-all tick offset (i.e. how many ticks ago) and how wide of a maximum delta time will be used for the /// various . @@ -4561,9 +4578,8 @@ private static void RemoveTickUpdate(NetworkManager networkManager) /// Having the tick update once and cycling through registered instances to update is evidently less processor /// intensive than having each instance subscribe and update individually. /// - private class NetworkTransformTickRegistration + internal class NetworkTransformTickRegistration { - private Action m_NetworkTickUpdate; private NetworkManager m_NetworkManager; public HashSet NetworkTransforms = new HashSet(); @@ -4575,8 +4591,6 @@ private void OnNetworkManagerStopped(bool value) public void Remove() { - m_NetworkManager.NetworkTickSystem.Tick -= m_NetworkTickUpdate; - m_NetworkTickUpdate = null; NetworkTransforms.Clear(); RemoveTickUpdate(m_NetworkManager); } @@ -4585,10 +4599,10 @@ public void Remove() /// Invoked once per network tick, this will update any registered /// authority instances. ///
- private void TickUpdate() + internal void TickUpdate() { // TODO FIX: The local NetworkTickSystem can invoke with the same network tick as before - if (m_NetworkManager.ServerTime.Tick <= m_LastTick) + if (CurrentTick <= m_LastTick) { return; } @@ -4599,13 +4613,11 @@ private void TickUpdate() networkTransform.OnNetworkTick(); } } - m_LastTick = m_NetworkManager.ServerTime.Tick; + m_LastTick = CurrentTick; } public NetworkTransformTickRegistration(NetworkManager networkManager) { m_NetworkManager = networkManager; - m_NetworkTickUpdate = new Action(TickUpdate); - networkManager.NetworkTickSystem.Tick += m_NetworkTickUpdate; if (networkManager.IsServer) { networkManager.OnServerStopped += OnNetworkManagerStopped; diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index f0e388d72e..2009de87bc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -9,6 +9,7 @@ #endif using UnityEngine.SceneManagement; using Debug = UnityEngine.Debug; +using Unity.Netcode.Components; namespace Unity.Netcode { @@ -386,7 +387,19 @@ public void NetworkUpdate(NetworkUpdateStage updateStage) #endif case NetworkUpdateStage.PreUpdate: { + var currentTick = ServerTime.Tick; NetworkTimeSystem.UpdateTime(); + if (ServerTime.Tick != currentTick) + { + // If we have a lower than expected frame rate and our number of ticks that have passed since the last + // frame is greater than 1, then use the first next tick as opposed to the last tick when checking for + // changes in transform state. + // Note: This is an adjustment from using the NetworkTick event as that can be invoked more than once in + // a single frame under the above condition and since any changes to the transform are frame driven there + // is no need to check for changes to the transform more than once per frame. + NetworkTransform.CurrentTick = (ServerTime.Tick - currentTick) > 1 ? currentTick + 1 : ServerTime.Tick; + NetworkTransform.UpdateNetworkTick(this); + } AnticipationSystem.Update(); } break; From e7c859caaf060117116ba8387240c74c564529bb Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 21 Apr 2025 11:01:02 -0500 Subject: [PATCH 4/7] update updating changelog. --- com.unity.netcode.gameobjects/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 6a9a6c8f5c..219fd15124 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -13,6 +13,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed issue where the authority instance of NetworkTransform could check for state updates more than one time in a frame if the frame rate is greater than the tick frequency. (#3413) - Fixed issue where the new interpolator types were blocking after the first consumption of a sequence of buffered state updates. (#3413) - Fixed issue where root level in-scene placed `NetworkObject`s would only allow the ownership permission to be no less than distributable or sessionowner. (#3407) From d56c6610821bf7b53e863a57863b7b73a91e9783 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 21 Apr 2025 18:25:20 -0500 Subject: [PATCH 5/7] test Adding the test to validate the fix for an object in motion coming to a rest where the interpolator has detected no additional state updates, reset itself, and then the object starts moving again (for longer than 3-10x the tick frequency) then the time between the first new state update and the second state update should not exceed the given tick frequency if both state updates happened sequentially (tick relative). --- .../InterpolationStopAndStartMotionTest.cs | 235 ++++++++++++++++++ ...nterpolationStopAndStartMotionTest.cs.meta | 2 + 2 files changed, 237 insertions(+) create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs.meta diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs new file mode 100644 index 0000000000..99df6b2f16 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs @@ -0,0 +1,235 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Unity.Netcode.Components; +using Unity.Netcode.TestHelpers.Runtime; +using UnityEngine; +using UnityEngine.TestTools; + +namespace Unity.Netcode.RuntimeTests +{ + [TestFixture(HostOrServer.Host, NetworkTransform.InterpolationTypes.Lerp)] + [TestFixture(HostOrServer.Host, NetworkTransform.InterpolationTypes.SmoothDampening)] + [TestFixture(HostOrServer.DAHost, NetworkTransform.InterpolationTypes.Lerp)] + [TestFixture(HostOrServer.DAHost, NetworkTransform.InterpolationTypes.SmoothDampening)] + internal class InterpolationStopAndStartMotionTest : IntegrationTestWithApproximation + { + protected override int NumberOfClients => 2; + + private GameObject m_TestPrefab; + + private TestStartStopTransform m_AuthorityInstance; + private List m_NonAuthorityInstances = new List(); + + private NetworkTransform.InterpolationTypes m_InterpolationType; + private List m_NetworkManagers = new List(); + private NetworkManager m_AuthorityNetworkManager; + + private int m_NumberOfUpdates; + private Vector3 m_Direction; + + public InterpolationStopAndStartMotionTest(HostOrServer hostOrServer, NetworkTransform.InterpolationTypes interpolationType) : base(hostOrServer) + { + m_InterpolationType = interpolationType; + } + + protected override void OnServerAndClientsCreated() + { + m_TestPrefab = CreateNetworkObjectPrefab("TestObj"); + var testStartStopTransform = m_TestPrefab.AddComponent(); + testStartStopTransform.PositionInterpolationType = m_InterpolationType; + base.OnServerAndClientsCreated(); + } + + private bool WaitForInstancesToSpawn() + { + foreach (var networkManager in m_NetworkManagers) + { + if (networkManager == m_AuthorityNetworkManager) + { + continue; + } + + if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_AuthorityInstance.NetworkObjectId)) + { + return false; + } + } + return true; + } + + private bool WaitForInstancesToFinishInterpolation() + { + m_NonAuthorityInstances.Clear(); + foreach (var networkManager in m_NetworkManagers) + { + if (networkManager == m_AuthorityNetworkManager) + { + continue; + } + + if (!networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_AuthorityInstance.NetworkObjectId)) + { + return false; + } + + var nonAuthority = networkManager.SpawnManager.SpawnedObjects[m_AuthorityInstance.NetworkObjectId].GetComponent(); + + // Each non-authority instance needs to have reached their final target and reset waiting for the + // object to start moving again. + var positionInterpolator = nonAuthority.GetPositionInterpolator(); + if (positionInterpolator.InterpolateState.Target.HasValue) + { + return false; + } + + if (!Approximately(nonAuthority.transform.position, m_AuthorityInstance.transform.position)) + { + return false; + } + + m_NonAuthorityInstances.Add(nonAuthority); + } + return true; + } + + [UnityTest] + public IEnumerator StopAndStartMotion() + { + m_NetworkManagers.AddRange(m_ClientNetworkManagers); + if (!UseCMBService()) + { + m_NetworkManagers.Insert(0, m_ServerNetworkManager); + } + m_AuthorityNetworkManager = m_NetworkManagers[0]; + + m_AuthorityInstance = SpawnObject(m_TestPrefab, m_AuthorityNetworkManager).GetComponent(); + // Wait for all clients to spawn the instance + yield return WaitForConditionOrTimeOut(WaitForInstancesToSpawn); + AssertOnTimeout($"Not all clients spawned {m_AuthorityInstance.name}!"); + + ////// Start Motion + // Have authority move in a direction for a short period of time + m_Direction = GetRandomVector3(-10, 10).normalized; + m_NumberOfUpdates = 0; + m_AuthorityNetworkManager.NetworkTickSystem.Tick += NetworkTickSystem_Tick; + + yield return WaitForConditionOrTimeOut(() => m_NumberOfUpdates >= 10); + AssertOnTimeout($"Timed out waiting for all updates to be applied to the authority instance!"); + + ////// Finish interpolating and wait for each interpolator to detect a stop in the motion + // Wait for all non-authority instances to finish interpolating to the final destination point. + yield return WaitForConditionOrTimeOut(WaitForInstancesToFinishInterpolation); + AssertOnTimeout($"Not all clients finished interpolating {m_AuthorityInstance.name}!"); + + // Start recording the state updates on the non-authority instances + foreach (var testTransform in m_NonAuthorityInstances) + { + testTransform.CheckStateUpdates = true; + } + + ////// Stop to Start motion begins here + m_Direction = GetRandomVector3(-10, 10).normalized; + m_NumberOfUpdates = 0; + m_AuthorityNetworkManager.NetworkTickSystem.Tick += NetworkTickSystem_Tick; + + yield return WaitForConditionOrTimeOut(() => m_NumberOfUpdates >= 10); + AssertOnTimeout($"Timed out waiting for all updates to be applied to the authority instance!"); + + // Wait for all non-authority instances to finish interpolating to the final destination point. + yield return WaitForConditionOrTimeOut(WaitForInstancesToFinishInterpolation); + AssertOnTimeout($"Not all clients finished interpolating {m_AuthorityInstance.name}!"); + + // Checks that the time between the first and second state update is approximately the tick frequency + foreach (var testTransform in m_NonAuthorityInstances) + { + var deltaVariance = testTransform.GetTimeDeltaVarience(); + Assert.True(Approximately(deltaVariance, s_DefaultWaitForTick.waitTime), $"{testTransform.name}'s delta variance was {deltaVariance} when it should have been approximately {s_DefaultWaitForTick.waitTime}!"); + } + } + + /// + /// Moves the authority instance once per tick to simulate a change in transform state that occurs + /// every tick. + /// + private void NetworkTickSystem_Tick() + { + m_NumberOfUpdates++; + m_AuthorityInstance.transform.position = m_AuthorityInstance.transform.position + m_Direction * 2; + if (m_NumberOfUpdates >= 10) + { + m_AuthorityNetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick; + } + } + + internal class TestStartStopTransform : NetworkTransform + { + + public bool CheckStateUpdates; + + private BufferedLinearInterpolatorVector3 m_PosInterpolator; + + private Dictionary m_StatesProcessed = new Dictionary(); + + public struct StateEntry + { + public float TimeAdded; + public BufferedLinearInterpolator.CurrentState State; + } + + protected override void Awake() + { + base.Awake(); + m_PosInterpolator = GetPositionInterpolator(); + } + + /// + /// Checks the time that passed between the first and second state updates. + /// + /// time passed as a float + public float GetTimeDeltaVarience() + { + var stateKeys = m_StatesProcessed.Keys.ToList(); + var firstState = m_StatesProcessed[stateKeys[0]]; + var secondState = m_StatesProcessed[stateKeys[1]]; + + var firstAndSecondTimeDelta = secondState.TimeAdded - firstState.TimeAdded; + + // Get the delta time between the two times of both the first and second state. + // Then add the time it should have taken to get to the second state, and this should be the total time to interpolate + // from the current position to the target position of the second state update. + var stateDelta = (float)(secondState.State.Target.Value.TimeSent - firstState.State.Target.Value.TimeSent + secondState.State.TimeToTargetValue); + // Return the time detla between the time that passed and the time that should have passed processing the states. + return Mathf.Abs(stateDelta - firstAndSecondTimeDelta); + } + + public override void OnUpdate() + { + base.OnUpdate(); + + // If we are checking the state updates, then we want to track each unique state update + if (CheckStateUpdates) + { + // Make sure we have a valid target + if (m_PosInterpolator.InterpolateState.Target.HasValue) + { + // If the state update's identifier is different + var itemId = m_PosInterpolator.InterpolateState.Target.Value.ItemId; + if (!m_StatesProcessed.ContainsKey(itemId)) + { + // Add it to the table of state updates + var stateEntry = new StateEntry() + { + TimeAdded = Time.realtimeSinceStartup, + State = m_PosInterpolator.InterpolateState, + }; + + m_StatesProcessed.Add(itemId, stateEntry); + } + } + } + } + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs.meta new file mode 100644 index 0000000000..9e04350607 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/InterpolationStopAndStartMotionTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 098d70b36b853da4c98b12d30298be9d \ No newline at end of file From 5ca720df76454c6cca85463a86618fbce85bbc6c Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 21 Apr 2025 18:36:25 -0500 Subject: [PATCH 6/7] test fix Adding an internal version of GetPositionInterpolator and GetRotationInterpolator when DEBUG_LINEARBUFFER is not defined for testing purposes. --- .../Runtime/Components/NetworkTransform.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index ecdec58fcf..b2730c3f61 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -4035,6 +4035,16 @@ public BufferedLinearInterpolatorQuaternion GetRotationInterpolator() { return m_RotationInterpolator; } +#else + internal BufferedLinearInterpolatorVector3 GetPositionInterpolator() + { + return m_PositionInterpolator; + } + + internal BufferedLinearInterpolatorQuaternion GetRotationInterpolator() + { + return m_RotationInterpolator; + } #endif public int GetPositionBufferCount() { From 044496c4c6a39c280788b6306f45288dd0acde8d Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Mon, 21 Apr 2025 18:38:56 -0500 Subject: [PATCH 7/7] test-fix-II Wrong #if --- .../Runtime/Components/NetworkTransform.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index b2730c3f61..05eeb22cfe 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -4035,16 +4035,6 @@ public BufferedLinearInterpolatorQuaternion GetRotationInterpolator() { return m_RotationInterpolator; } -#else - internal BufferedLinearInterpolatorVector3 GetPositionInterpolator() - { - return m_PositionInterpolator; - } - - internal BufferedLinearInterpolatorQuaternion GetRotationInterpolator() - { - return m_RotationInterpolator; - } #endif public int GetPositionBufferCount() { @@ -4065,6 +4055,16 @@ public double GetPositionLastRemainingTime() { return m_PositionInterpolator.InterpolateState.LastRemainingTime; } +#else + internal BufferedLinearInterpolatorVector3 GetPositionInterpolator() + { + return m_PositionInterpolator; + } + + internal BufferedLinearInterpolatorQuaternion GetRotationInterpolator() + { + return m_RotationInterpolator; + } #endif // Non-Authority