diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md
index ffedfbeb0b..a5d6e56264 100644
--- a/com.unity.netcode.gameobjects/CHANGELOG.md
+++ b/com.unity.netcode.gameobjects/CHANGELOG.md
@@ -12,6 +12,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
### Changed
+- Improve performance of `NetworkBehavior`. (#3915)
+- Improve performance of `NetworkTransform`. (#3907)
- Improve performance of `NetworkRigidbodyBase`. (#3906)
- Improve performance of `NetworkAnimator`. (#3905)
diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs
index 64e9bc0b95..972cdbd689 100644
--- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs
@@ -1621,10 +1621,11 @@ internal bool SynchronizeScale
public bool CanCommitToTransform { get; protected set; }
///
- /// Internally used by to keep track of the instance assigned to this
+ /// Internally used by to keep track of the instance assigned to
/// this derived class instance.
///
protected NetworkManager m_CachedNetworkManager;
+ private int m_CachedTickRate;
///
/// Helper method that returns the space relative position of the transform.
@@ -2136,9 +2137,8 @@ private bool CheckForStateChange(ref NetworkTransformState networkState, bool is
// We compare against the NetworkTickSystem version since ServerTime is set when updating ticks
if (UseUnreliableDeltas && !isSynchronization && m_DeltaSynch && m_NextTickSync <= CurrentTick)
{
- // TODO-CACHE: m_CachedNetworkManager.NetworkConfig.TickRate value
// Increment to the next frame synch tick position for this instance
- m_NextTickSync += (int)m_CachedNetworkManager.NetworkConfig.TickRate;
+ m_NextTickSync += m_CachedTickRate;
// If we are teleporting, we do not need to send a frame synch for this tick slot
// as a "frame synch" really is effectively just a teleport.
isAxisSync = !flagStates.IsTeleportingNextFrame;
@@ -2606,7 +2606,7 @@ private void OnNetworkTick(bool isCalledFromParent = false)
}
else // If we are no longer authority, unsubscribe to the tick event
{
- DeregisterForTickUpdate(this);
+ DeregisterForTickUpdate();
}
}
#endregion
@@ -3537,7 +3537,7 @@ private void ApplyPlayerTransformState()
///
/// For dynamically spawned NetworkObjects, when the non-authority instance's client is already connected and
- /// the SynchronizeState is still pending synchronization then we want to finalize the synchornization at this time.
+ /// the SynchronizeState is still pending synchronization then we want to finalize the synchronization at this time.
///
protected internal override void InternalOnNetworkPostSpawn()
{
@@ -3550,7 +3550,7 @@ protected internal override void InternalOnNetworkPostSpawn()
// Then we want to:
// - Force the "IsSynchronizing" flag so the NetworkTransform has its state updated properly and runs through the initialization again.
// - Make sure the SynchronizingState is updated to the instantiated prefab's default flags/settings.
- if (NetworkManager.IsServer && !NetworkManager.DistributedAuthorityMode && !IsOwner && !OnIsServerAuthoritative() && !SynchronizeState.IsSynchronizing)
+ if (m_CachedNetworkManager.IsServer && !m_CachedNetworkManager.DistributedAuthorityMode && !IsOwner && !OnIsServerAuthoritative() && !SynchronizeState.IsSynchronizing)
{
// Handle the first/root NetworkTransform slightly differently to have a sequenced synchronization of like authority nested NetworkTransform components
if (m_IsFirstNetworkTransform)
@@ -3578,7 +3578,7 @@ protected internal override void InternalOnNetworkPostSpawn()
}
// Standard non-authority synchronization is handled here
- if (!CanCommitToTransform && NetworkManager.IsConnectedClient && SynchronizeState.IsSynchronizing)
+ if (!CanCommitToTransform && m_CachedNetworkManager.IsConnectedClient && SynchronizeState.IsSynchronizing)
{
NonAuthorityFinalizeSynchronization();
}
@@ -3631,7 +3631,6 @@ internal override void InternalOnNetworkPreSpawn(ref NetworkManager networkManag
public override void OnNetworkSpawn()
{
m_ParentedChildren.Clear();
- m_CachedNetworkManager = NetworkManager;
Initialize();
@@ -3639,6 +3638,7 @@ public override void OnNetworkSpawn()
{
SetState(GetSpaceRelativePosition(), GetSpaceRelativeRotation(), GetScale(), false);
}
+ base.OnNetworkSpawn();
}
private void CleanUpOnDestroyOrDespawn()
@@ -3651,10 +3651,10 @@ private void CleanUpOnDestroyOrDespawn()
#endif
if (m_CachedNetworkObject != null)
{
- NetworkManager?.NetworkTransformRegistration(m_CachedNetworkObject, forUpdate, false);
+ m_CachedNetworkManager.NetworkTransformRegistration(m_CachedNetworkObject, forUpdate, false);
}
- DeregisterForTickUpdate(this);
+ DeregisterForTickUpdate();
CanCommitToTransform = false;
}
@@ -3697,7 +3697,7 @@ protected virtual void OnInitialize(ref NetworkVariable r
///
private void ResetInterpolatedStateToCurrentAuthoritativeState()
{
- var serverTime = NetworkManager.ServerTime.Time;
+ var serverTime = m_CachedNetworkManager.ServerTime.Time;
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
var position = m_UseRigidbodyForMotion ? m_NetworkRigidbodyInternal.GetPosition() : GetSpaceRelativePosition();
var rotation = m_UseRigidbodyForMotion ? m_NetworkRigidbodyInternal.GetRotation() : GetSpaceRelativeRotation();
@@ -3719,7 +3719,7 @@ private void ResetInterpolatedStateToCurrentAuthoritativeState()
}
private NetworkObject m_CachedNetworkObject;
///
- /// The internal initialzation method to allow for internal API adjustments
+ /// The internal initialization method to allow for internal API adjustments
///
///
private void InternalInitialization(bool isOwnershipChange = false)
@@ -3729,9 +3729,10 @@ private void InternalInitialization(bool isOwnershipChange = false)
return;
}
m_CachedNetworkObject = NetworkObject;
+ m_CachedTickRate = (int)m_CachedNetworkManager.NetworkConfig.TickRate;
// Determine if this is the first NetworkTransform in the associated NetworkObject's list
- m_IsFirstNetworkTransform = NetworkObject.NetworkTransforms[0] == this;
+ m_IsFirstNetworkTransform = m_CachedNetworkObject.NetworkTransforms[0] == this;
if (m_CachedNetworkManager && m_CachedNetworkManager.DistributedAuthorityMode)
{
@@ -3755,9 +3756,9 @@ private void InternalInitialization(bool isOwnershipChange = false)
var currentPosition = GetSpaceRelativePosition();
var currentRotation = GetSpaceRelativeRotation();
- if (NetworkManager.DistributedAuthorityMode)
+ if (m_CachedNetworkManager.DistributedAuthorityMode)
{
- RegisterNetworkManagerForTickUpdate(NetworkManager);
+ RegisterNetworkManagerForTickUpdate(m_CachedNetworkManager);
}
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
@@ -3793,7 +3794,7 @@ private void InternalInitialization(bool isOwnershipChange = false)
m_InternalCurrentPosition = currentPosition;
m_LastStateTargetPosition = currentPosition;
- RegisterForTickUpdate(this);
+ RegisterForTickUpdate();
if (UseHalfFloatPrecision && isOwnershipChange && !IsServerAuthoritative() && Interpolate)
{
@@ -3813,7 +3814,7 @@ private void InternalInitialization(bool isOwnershipChange = false)
// Non-authority needs to be added to updates for interpolation and applying state purposes
m_CachedNetworkManager.NetworkTransformRegistration(NetworkObject, forUpdate, true);
// Remove this instance from the tick update
- DeregisterForTickUpdate(this);
+ DeregisterForTickUpdate();
ResetInterpolatedStateToCurrentAuthoritativeState();
m_InternalCurrentPosition = currentPosition;
m_LastStateTargetPosition = currentPosition;
@@ -3941,7 +3942,7 @@ internal override void InternalOnNetworkObjectParentChanged(NetworkObject parent
if (LastTickSync == m_LocalAuthoritativeNetworkState.GetNetworkTick())
{
m_InternalCurrentPosition = m_LastStateTargetPosition = GetSpaceRelativePosition();
- m_PositionInterpolator.ResetTo(m_PositionInterpolator.Parent, m_InternalCurrentPosition, NetworkManager.ServerTime.Time);
+ m_PositionInterpolator.ResetTo(m_PositionInterpolator.Parent, m_InternalCurrentPosition, m_CachedNetworkManager.ServerTime.Time);
if (InLocalSpace)
{
transform.localPosition = m_InternalCurrentPosition;
@@ -3973,7 +3974,7 @@ internal override void InternalOnNetworkObjectParentChanged(NetworkObject parent
{
m_InternalCurrentRotation = GetSpaceRelativeRotation();
m_TargetRotation = m_InternalCurrentRotation.eulerAngles;
- m_RotationInterpolator.ResetTo(m_RotationInterpolator.Parent, m_InternalCurrentRotation, NetworkManager.ServerTime.Time);
+ m_RotationInterpolator.ResetTo(m_RotationInterpolator.Parent, m_InternalCurrentRotation, m_CachedNetworkManager.ServerTime.Time);
if (InLocalSpace)
{
transform.localRotation = m_InternalCurrentRotation;
@@ -4596,7 +4597,7 @@ internal void TransformStateUpdate()
{
// TODO: Investigate where this state should be applied or just discarded.
// For now, discard the state if we assumed ownership.
- // Debug.Log($"[Client-{NetworkManager.LocalClientId}] Ignoring inbound update from Client-{0} and parentUpdated:{isParentingDirective}!");
+ // Debug.Log($"[Client-{m_CachedNetworkManager.LocalClientId}] Ignoring inbound update from Client-{0} and parentUpdated:{isParentingDirective}!");
return;
}
// Store the previous/old state
@@ -4653,17 +4654,17 @@ private void UpdateTransformState()
{
continue;
}
- if (!NetworkObject.Observers.Contains(clientId))
+ if (!m_CachedNetworkObject.Observers.Contains(clientId))
{
continue;
}
- NetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, clientId);
+ m_CachedNetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, clientId);
}
}
else
{
// Clients (owner authoritative) send messages to the server-host
- NetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, NetworkManager.ServerClientId);
+ m_CachedNetworkManager.MessageManager.SendMessage(ref m_OutboundMessage, networkDelivery, NetworkManager.ServerClientId);
}
m_LocalAuthoritativeNetworkState.LastSerializedSize = m_OutboundMessage.BytesWritten;
}
@@ -4802,7 +4803,7 @@ public NetworkTransformTickRegistration(NetworkManager networkManager)
internal void RegisterForTickSynchronization()
{
s_TickSynchPosition++;
- m_NextTickSync = NetworkManager.ServerTime.Tick + (s_TickSynchPosition % (int)NetworkManager.NetworkConfig.TickRate);
+ m_NextTickSync = m_CachedNetworkManager.ServerTime.Tick + (s_TickSynchPosition % m_CachedTickRate);
}
private static void RegisterNetworkManagerForTickUpdate(NetworkManager networkManager)
@@ -4818,36 +4819,34 @@ private static void RegisterNetworkManagerForTickUpdate(NetworkManager networkMa
/// If a NetworkTransformTickRegistration has not yet been registered for the NetworkManager
/// instance, then create an entry.
///
- ///
- private static void RegisterForTickUpdate(NetworkTransform networkTransform)
+ private void RegisterForTickUpdate()
{
- if (!networkTransform.NetworkManager.DistributedAuthorityMode && !s_NetworkTickRegistration.ContainsKey(networkTransform.NetworkManager))
+ if (!m_CachedNetworkManager.DistributedAuthorityMode && !s_NetworkTickRegistration.ContainsKey(m_CachedNetworkManager))
{
- s_NetworkTickRegistration.Add(networkTransform.NetworkManager, new NetworkTransformTickRegistration(networkTransform.NetworkManager));
+ s_NetworkTickRegistration.Add(m_CachedNetworkManager, new NetworkTransformTickRegistration(m_CachedNetworkManager));
}
- networkTransform.RegisterForTickSynchronization();
- s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Add(networkTransform);
+ RegisterForTickSynchronization();
+ s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Add(this);
}
///
/// If a NetworkTransformTickRegistration exists for the NetworkManager instance, then this will
/// remove the NetworkTransform instance from the single tick update entry point.
///
- ///
- private static void DeregisterForTickUpdate(NetworkTransform networkTransform)
+ private void DeregisterForTickUpdate()
{
- if (networkTransform.NetworkManager == null)
+ if (m_CachedNetworkManager == null)
{
return;
}
- if (s_NetworkTickRegistration.ContainsKey(networkTransform.NetworkManager))
+ if (s_NetworkTickRegistration.ContainsKey(m_CachedNetworkManager))
{
- s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Remove(networkTransform);
- if (!networkTransform.NetworkManager.DistributedAuthorityMode && s_NetworkTickRegistration[networkTransform.NetworkManager].NetworkTransforms.Count == 0)
+ s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Remove(this);
+ if (!m_CachedNetworkManager.DistributedAuthorityMode && s_NetworkTickRegistration[m_CachedNetworkManager].NetworkTransforms.Count == 0)
{
- var registrationEntry = s_NetworkTickRegistration[networkTransform.NetworkManager];
+ var registrationEntry = s_NetworkTickRegistration[m_CachedNetworkManager];
registrationEntry.Remove();
}
}
diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs
index 3d3c919986..049f28070b 100644
--- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs
@@ -90,7 +90,6 @@ internal FastBufferWriter __beginSendServerRpc(uint rpcMethodId, ServerRpcParams
internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMethodId, ServerRpcParams serverRpcParams, RpcDelivery rpcDelivery)
#pragma warning restore IDE1006 // restore naming rule violation check
{
- var networkManager = m_NetworkManager;
var serverRpcMessage = new ServerRpcMessage
{
Metadata = new RpcMetadata
@@ -110,7 +109,7 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
networkDelivery = MessageDeliveryType.DefaultDelivery;
break;
case RpcDelivery.Unreliable:
- if (bufferWriter.Length > networkManager.MessageManager.NonFragmentedMessageMaxSize)
+ if (bufferWriter.Length > m_NetworkManager.MessageManager.NonFragmentedMessageMaxSize)
{
throw new OverflowException("RPC parameters are too large for unreliable delivery.");
}
@@ -127,8 +126,8 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
var context = new NetworkContext
{
SenderId = NetworkManager.ServerClientId,
- Timestamp = networkManager.RealTimeProvider.RealTimeSinceStartup,
- SystemOwner = networkManager,
+ Timestamp = m_NetworkManager.RealTimeProvider.RealTimeSinceStartup,
+ SystemOwner = m_NetworkManager,
// header information isn't valid since it's not a real message.
// RpcMessage doesn't access this stuff so it's just left empty.
Header = new NetworkMessageHeader(),
@@ -141,7 +140,7 @@ internal void __endSendServerRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
}
else
{
- rpcWriteSize = networkManager.ConnectionManager.SendMessage(ref serverRpcMessage, networkDelivery, NetworkManager.ServerClientId);
+ rpcWriteSize = m_NetworkManager.ConnectionManager.SendMessage(ref serverRpcMessage, networkDelivery, NetworkManager.ServerClientId);
}
bufferWriter.Dispose();
@@ -169,7 +168,6 @@ internal FastBufferWriter __beginSendClientRpc(uint rpcMethodId, ClientRpcParams
internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMethodId, ClientRpcParams clientRpcParams, RpcDelivery rpcDelivery)
#pragma warning restore IDE1006 // restore naming rule violation check
{
- var networkManager = m_NetworkManager;
var clientRpcMessage = new ClientRpcMessage
{
Metadata = new RpcMetadata
@@ -189,7 +187,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
networkDelivery = MessageDeliveryType.DefaultDelivery;
break;
case RpcDelivery.Unreliable:
- if (bufferWriter.Length > networkManager.MessageManager.NonFragmentedMessageMaxSize)
+ if (bufferWriter.Length > m_NetworkManager.MessageManager.NonFragmentedMessageMaxSize)
{
throw new OverflowException("RPC parameters are too large for unreliable delivery.");
}
@@ -212,7 +210,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
continue;
}
// Check to make sure we are sending to only observers, if not log an error.
- if (networkManager.LogLevel >= LogLevel.Error && !m_NetworkObject.Observers.Contains(targetClientId))
+ if (m_NetworkManager.LogLevel >= LogLevel.Error && !m_NetworkObject.Observers.Contains(targetClientId))
{
NetworkLog.LogError(GenerateObserverErrorMessage(clientRpcParams, targetClientId));
}
@@ -229,12 +227,12 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
continue;
}
// Check to make sure we are sending to only observers, if not log an error.
- if (networkManager.LogLevel >= LogLevel.Error && !m_NetworkObject.Observers.Contains(targetClientId))
+ if (m_NetworkManager.LogLevel >= LogLevel.Error && !m_NetworkObject.Observers.Contains(targetClientId))
{
NetworkLog.LogError(GenerateObserverErrorMessage(clientRpcParams, targetClientId));
}
}
- rpcWriteSize = networkManager.ConnectionManager.SendMessage(ref clientRpcMessage, networkDelivery, clientRpcParams.Send.TargetClientIdsNativeArray.Value);
+ rpcWriteSize = m_NetworkManager.ConnectionManager.SendMessage(ref clientRpcMessage, networkDelivery, clientRpcParams.Send.TargetClientIdsNativeArray.Value);
}
else
{
@@ -242,12 +240,12 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
while (observerEnumerator.MoveNext())
{
// Skip over the host
- if (IsHost && observerEnumerator.Current == networkManager.LocalClientId)
+ if (IsHost && observerEnumerator.Current == m_NetworkManager.LocalClientId)
{
shouldInvokeLocally = true;
continue;
}
- rpcWriteSize = networkManager.ConnectionManager.SendMessage(ref clientRpcMessage, networkDelivery, observerEnumerator.Current);
+ rpcWriteSize = m_NetworkManager.ConnectionManager.SendMessage(ref clientRpcMessage, networkDelivery, observerEnumerator.Current);
}
}
@@ -258,8 +256,8 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
var context = new NetworkContext
{
SenderId = NetworkManager.ServerClientId,
- Timestamp = networkManager.RealTimeProvider.RealTimeSinceStartup,
- SystemOwner = networkManager,
+ Timestamp = m_NetworkManager.RealTimeProvider.RealTimeSinceStartup,
+ SystemOwner = m_NetworkManager,
// header information isn't valid since it's not a real message.
// RpcMessage doesn't access this stuff so it's just left empty.
Header = new NetworkMessageHeader(),
@@ -282,7 +280,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
{
foreach (var targetClientId in clientRpcParams.Send.TargetClientIds)
{
- networkManager.NetworkMetrics.TrackRpcSent(
+ m_NetworkManager.NetworkMetrics.TrackRpcSent(
targetClientId,
m_NetworkObject,
rpcMethodName,
@@ -294,7 +292,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
{
foreach (var targetClientId in clientRpcParams.Send.TargetClientIdsNativeArray)
{
- networkManager.NetworkMetrics.TrackRpcSent(
+ m_NetworkManager.NetworkMetrics.TrackRpcSent(
targetClientId,
m_NetworkObject,
rpcMethodName,
@@ -307,7 +305,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
var observerEnumerator = m_NetworkObject.Observers.GetEnumerator();
while (observerEnumerator.MoveNext())
{
- networkManager.NetworkMetrics.TrackRpcSent(
+ m_NetworkManager.NetworkMetrics.TrackRpcSent(
observerEnumerator.Current,
m_NetworkObject,
rpcMethodName,
@@ -325,7 +323,7 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
internal FastBufferWriter __beginSendRpc(uint rpcMethodId, RpcParams rpcParams, RpcAttribute.RpcAttributeParams attributeParams, SendTo defaultTarget, RpcDelivery rpcDelivery)
#pragma warning restore IDE1006 // restore naming rule violation check
{
- if (m_NetworkObject == null && !IsSpawned)
+ if (!IsSpawned)
{
throw new RpcException("The NetworkBehaviour must be spawned before calling this method.");
}
@@ -652,27 +650,24 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)
///
internal void UpdateNetworkProperties()
{
- var networkObject = m_NetworkObject;
- var networkManager = m_NetworkManager;
-
// Set identification related properties
- NetworkObjectId = networkObject.NetworkObjectId;
- IsLocalPlayer = networkObject.IsLocalPlayer;
+ NetworkObjectId = m_NetworkObject.NetworkObjectId;
+ IsLocalPlayer = m_NetworkObject.IsLocalPlayer;
// Set ownership related properties
- IsOwnedByServer = networkObject.IsOwnedByServer;
- IsOwner = networkObject.IsOwner;
- OwnerClientId = networkObject.OwnerClientId;
+ IsOwnedByServer = m_NetworkObject.IsOwnedByServer;
+ IsOwner = m_NetworkObject.IsOwner;
+ OwnerClientId = m_NetworkObject.OwnerClientId;
// Set NetworkManager dependent properties
- if (networkManager != null)
- {
- IsHost = networkManager.IsListening && networkManager.IsHost;
- IsClient = networkManager.IsListening && networkManager.IsClient;
- IsServer = networkManager.IsListening && networkManager.IsServer;
- IsSessionOwner = networkManager.IsListening && networkManager.LocalClient.IsSessionOwner;
- HasAuthority = networkObject.HasAuthority;
- ServerIsHost = networkManager.IsListening && networkManager.ServerIsHost;
+ if (m_NetworkManager != null)
+ {
+ IsHost = m_NetworkManager.IsListening && m_NetworkManager.IsHost;
+ IsClient = m_NetworkManager.IsListening && m_NetworkManager.IsClient;
+ IsServer = m_NetworkManager.IsListening && m_NetworkManager.IsServer;
+ IsSessionOwner = m_NetworkManager.IsListening && m_NetworkManager.LocalClient.IsSessionOwner;
+ HasAuthority = m_NetworkObject.HasAuthority;
+ ServerIsHost = m_NetworkManager.IsListening && m_NetworkManager.ServerIsHost;
}
}