@@ -499,6 +499,10 @@ public Quaternion GetRotation()
499499 /// <remarks>
500500 /// When there is no change in an updated state's position then there are no values to return.
501501 /// Checking for <see cref="HasPositionChange"/> is one way to detect this.
502+ /// When used with half precision it returns the half precision delta position state update
503+ /// which will not be the full position.
504+ /// To get a NettworkTransform's full position, use <see cref="GetSpaceRelativePosition(bool)"/> and
505+ /// pass true as the parameter.
502506 /// </remarks>
503507 /// <returns><see cref="Vector3"/></returns>
504508 public Vector3 GetPosition ( )
@@ -1110,7 +1114,16 @@ public Vector3 GetSpaceRelativePosition(bool getCurrentState = false)
11101114 }
11111115 else
11121116 {
1113- return m_CurrentPosition ;
1117+ // When half float precision is enabled, get the NetworkDeltaPosition's full position
1118+ if ( UseHalfFloatPrecision )
1119+ {
1120+ return m_HalfPositionState . GetFullPosition ( ) ;
1121+ }
1122+ else
1123+ {
1124+ // Otherwise, just get the current position
1125+ return m_CurrentPosition ;
1126+ }
11141127 }
11151128 }
11161129
@@ -1393,6 +1406,8 @@ protected virtual void OnAuthorityPushTransformState(ref NetworkTransformState n
13931406 {
13941407 }
13951408
1409+ // Tracks the last tick a state update was sent (see further below)
1410+ private int m_LastTick ;
13961411 /// <summary>
13971412 /// Authoritative side only
13981413 /// If there are any transform delta states, this method will synchronize the
@@ -1411,11 +1426,27 @@ private void TryCommitTransform(ref Transform transformToCommit, bool synchroniz
14111426 if ( ApplyTransformToNetworkStateWithInfo ( ref m_LocalAuthoritativeNetworkState , ref transformToCommit , synchronize ) )
14121427 {
14131428 m_LocalAuthoritativeNetworkState . LastSerializedSize = m_OldState . LastSerializedSize ;
1414- OnAuthorityPushTransformState ( ref m_LocalAuthoritativeNetworkState ) ;
14151429
1430+ // Make sure our network tick is incremented
1431+ if ( m_LastTick == m_LocalAuthoritativeNetworkState . NetworkTick && ! m_LocalAuthoritativeNetworkState . IsTeleportingNextFrame )
1432+ {
1433+ // When running in authority and a remote client is the owner, the client can hit a perfect window of time where
1434+ // it is still on the previous network tick (as a count) but still have had the tick event triggered.
1435+ // (This is cheaper than calculating the exact tick each time and only can occur on clients)
1436+ if ( ! IsServer )
1437+ {
1438+ m_LocalAuthoritativeNetworkState . NetworkTick = m_LocalAuthoritativeNetworkState . NetworkTick + 1 ;
1439+ }
1440+ else
1441+ {
1442+ NetworkLog . LogError ( $ "[NT TICK DUPLICATE] Server already sent an update on tick { m_LastTick } and is attempting to send again on the same network tick!") ;
1443+ }
1444+ }
1445+ m_LastTick = m_LocalAuthoritativeNetworkState . NetworkTick ;
14161446 // Update the state
14171447 UpdateTransformState ( ) ;
14181448
1449+ OnAuthorityPushTransformState ( ref m_LocalAuthoritativeNetworkState ) ;
14191450 m_LocalAuthoritativeNetworkState . IsTeleportingNextFrame = false ;
14201451 }
14211452 }
@@ -2209,6 +2240,7 @@ private void ApplyUpdatedState(NetworkTransformState newState)
22092240 m_HalfPositionState . HalfVector3 . Axis = m_LocalAuthoritativeNetworkState . NetworkDeltaPosition . HalfVector3 . Axis ;
22102241 // and update our target position
22112242 m_TargetPosition = m_HalfPositionState . ToVector3 ( newState . NetworkTick ) ;
2243+ m_LocalAuthoritativeNetworkState . NetworkDeltaPosition . CurrentBasePosition = m_HalfPositionState . CurrentBasePosition ;
22122244 m_LocalAuthoritativeNetworkState . CurrentPosition = m_TargetPosition ;
22132245 }
22142246
@@ -2455,6 +2487,9 @@ private void NetworkTickSystem_Tick()
24552487 // Update any changes to the transform
24562488 var transformSource = transform ;
24572489 OnUpdateAuthoritativeState ( ref transformSource ) ;
2490+
2491+ m_CurrentPosition = GetSpaceRelativePosition ( ) ;
2492+ m_TargetPosition = GetSpaceRelativePosition ( ) ;
24582493 }
24592494 else
24602495 {
@@ -2466,9 +2501,6 @@ private void NetworkTickSystem_Tick()
24662501 }
24672502 }
24682503
2469-
2470-
2471-
24722504 /// <inheritdoc/>
24732505 public override void OnNetworkSpawn ( )
24742506 {
@@ -2510,24 +2542,25 @@ public override void OnDestroy()
25102542 }
25112543
25122544 /// <inheritdoc/>
2513- public override void OnGainedOwnership ( )
2545+ public override void OnLostOwnership ( )
25142546 {
2515- // Only initialize if we gained ownership
2516- if ( OwnerClientId == NetworkManager . LocalClientId )
2517- {
2518- Initialize ( ) ;
2519- }
2547+ base . OnLostOwnership ( ) ;
25202548 }
25212549
25222550 /// <inheritdoc/>
2523- public override void OnLostOwnership ( )
2551+ public override void OnGainedOwnership ( )
25242552 {
2525- // Only initialize if we are not authority and lost
2526- // ownership
2527- if ( OwnerClientId != NetworkManager . LocalClientId )
2553+ base . OnGainedOwnership ( ) ;
2554+ }
2555+
2556+ protected override void OnOwnershipChanged ( ulong previous , ulong current )
2557+ {
2558+ // If we were the previous owner or the newly assigned owner then reinitialize
2559+ if ( current == NetworkManager . LocalClientId || previous == NetworkManager . LocalClientId )
25282560 {
25292561 Initialize ( ) ;
25302562 }
2563+ base . OnOwnershipChanged ( previous , current ) ;
25312564 }
25322565
25332566 /// <summary>
@@ -2552,6 +2585,7 @@ protected virtual void OnInitialize(ref NetworkVariable<NetworkTransformState> r
25522585
25532586 }
25542587
2588+
25552589 /// <summary>
25562590 /// Initializes NetworkTransform when spawned and ownership changes.
25572591 /// </summary>
@@ -2572,7 +2606,8 @@ protected void Initialize()
25722606 {
25732607 m_HalfPositionState = new NetworkDeltaPosition ( currentPosition , NetworkManager . NetworkTickSystem . ServerTime . Tick , math . bool3 ( SyncPositionX , SyncPositionY , SyncPositionZ ) ) ;
25742608 }
2575-
2609+ m_CurrentPosition = currentPosition ;
2610+ m_TargetPosition = currentPosition ;
25762611 // Authority only updates once per network tick
25772612 NetworkManager . NetworkTickSystem . Tick -= NetworkTickSystem_Tick ;
25782613 NetworkManager . NetworkTickSystem . Tick += NetworkTickSystem_Tick ;
@@ -2835,6 +2870,13 @@ public bool IsServerAuthoritative()
28352870 /// <param name="messagePayload">serialzied <see cref="NetworkTransformState"/></param>
28362871 private void TransformStateUpdate ( ulong senderId , FastBufferReader messagePayload )
28372872 {
2873+ if ( ! OnIsServerAuthoritative ( ) && IsServer && OwnerClientId == NetworkManager . ServerClientId )
2874+ {
2875+ // Ownership must have changed, ignore any additional pending messages that might have
2876+ // come from a previous owner client.
2877+ return ;
2878+ }
2879+
28382880 // Forward owner authoritative messages before doing anything else
28392881 if ( IsServer && ! OnIsServerAuthoritative ( ) )
28402882 {
@@ -2856,6 +2898,7 @@ private void TransformStateUpdate(ulong senderId, FastBufferReader messagePayloa
28562898 /// <param name="messagePayload">the owner state message payload</param>
28572899 private unsafe void ForwardStateUpdateMessage ( FastBufferReader messagePayload )
28582900 {
2901+ var serverAuthoritative = OnIsServerAuthoritative ( ) ;
28592902 var currentPosition = messagePayload . Position ;
28602903 var messageSize = messagePayload . Length - currentPosition ;
28612904 var writer = new FastBufferWriter ( messageSize , Allocator . Temp ) ;
@@ -2867,7 +2910,7 @@ private unsafe void ForwardStateUpdateMessage(FastBufferReader messagePayload)
28672910 for ( int i = 0 ; i < clientCount ; i ++ )
28682911 {
28692912 var clientId = NetworkManager . ConnectionManager . ConnectedClientsList [ i ] . ClientId ;
2870- if ( ! OnIsServerAuthoritative ( ) && ( NetworkManager . ServerClientId == clientId || clientId == OwnerClientId ) )
2913+ if ( NetworkManager . ServerClientId == clientId || ( ! serverAuthoritative && clientId == OwnerClientId ) )
28712914 {
28722915 continue ;
28732916 }
0 commit comments