Skip to content

Commit da50202

Browse files
EmandMNoelStephensUnity
authored andcommitted
Ensure NetworkManagerOwner is always correctly set
1 parent aea56fe commit da50202

9 files changed

Lines changed: 101 additions & 146 deletions

File tree

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
805805
// Spawn the player NetworkObject locally
806806
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(
807807
playerObject,
808+
NetworkManager,
808809
NetworkManager.SpawnManager.GetNetworkObjectId(),
809810
sceneObject: false,
810811
playerObject: true,
@@ -954,6 +955,7 @@ internal void CreateAndSpawnPlayer(ulong ownerId)
954955
var globalObjectIdHash = playerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
955956
var networkObject = NetworkManager.SpawnManager.GetNetworkObjectToSpawn(globalObjectIdHash, ownerId, playerPrefab.transform.position, playerPrefab.transform.rotation);
956957
networkObject.IsSceneObject = false;
958+
networkObject.NetworkManagerOwner = NetworkManager;
957959
networkObject.SpawnAsPlayerObject(ownerId, networkObject.DestroyWithScene);
958960
}
959961
}

com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,10 @@ internal bool IsBehaviourEditable()
548548
((networkManager.DistributedAuthorityMode && m_NetworkObject.IsOwner) || (!networkManager.DistributedAuthorityMode && networkManager.IsServer));
549549
}
550550

551-
internal void SetNetworkObject(NetworkObject networkObject)
551+
internal void SetNetworkObject(NetworkObject networkObject, ushort behaviourId)
552552
{
553553
m_NetworkObject = networkObject;
554+
NetworkBehaviourId = behaviourId;
554555
}
555556

556557
// TODO: this needs an overhaul. It's expensive, it's ja little naive in how it looks for networkObject in
@@ -615,11 +616,6 @@ public NetworkObject NetworkObject
615616
/// </summary>
616617
public ushort NetworkBehaviourId { get; internal set; }
617618

618-
/// <summary>
619-
/// Internally caches the Id of this behaviour in a NetworkObject. Makes look-up faster
620-
/// </summary>
621-
internal ushort NetworkBehaviourIdCache = 0;
622-
623619
/// <summary>
624620
/// Returns the NetworkBehaviour with a given BehaviourId for the current NetworkObject.
625621
/// </summary>
@@ -649,11 +645,6 @@ internal void UpdateNetworkProperties()
649645
NetworkObjectId = networkObject.NetworkObjectId;
650646
IsLocalPlayer = networkObject.IsLocalPlayer;
651647

652-
// This is "OK" because GetNetworkBehaviourOrderIndex uses the order of
653-
// NetworkObject.ChildNetworkBehaviours which is set once when first
654-
// accessed.
655-
NetworkBehaviourId = networkObject.GetNetworkBehaviourOrderIndex(this);
656-
657648
// Set ownership related properties
658649
IsOwnedByServer = networkObject.IsOwnedByServer;
659650
IsOwner = networkObject.IsOwner;
@@ -671,35 +662,6 @@ internal void UpdateNetworkProperties()
671662
}
672663
}
673664

674-
private void ResetAllFields()
675-
{
676-
m_NetworkObject = null;
677-
m_NetworkManager = null;
678-
RpcTarget = null;
679-
680-
// Set identification related properties
681-
NetworkObjectId = default;
682-
IsLocalPlayer = false;
683-
684-
// This is "OK" because GetNetworkBehaviourOrderIndex uses the order of
685-
// NetworkObject.ChildNetworkBehaviours which is set once when first
686-
// accessed.
687-
NetworkBehaviourId = default;
688-
689-
// Set ownership related properties
690-
IsOwnedByServer = false;
691-
IsOwner = false;
692-
OwnerClientId = default;
693-
694-
// Set NetworkManager dependent properties
695-
IsHost = false;
696-
IsClient = false;
697-
IsServer = false;
698-
IsSessionOwner = false;
699-
HasAuthority = false;
700-
ServerIsHost = false;
701-
}
702-
703665
/// <summary>
704666
/// Only for use in distributed authority mode.
705667
/// Invoked only on the authority instance when a <see cref="NetworkObject"/> is deferring its despawn on non-authoritative instances.
@@ -892,8 +854,6 @@ internal void InternalOnNetworkDespawn()
892854
{
893855
NetworkVariableFields[i].Deinitialize();
894856
}
895-
896-
ResetAllFields();
897857
}
898858

899859
/// <summary>
@@ -1130,7 +1090,6 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false
11301090
// Getting these ahead of time actually improves performance
11311091
var networkManager = NetworkManager;
11321092
var networkObject = m_NetworkObject;
1133-
var behaviourIndex = networkObject.GetNetworkBehaviourOrderIndex(this);
11341093
var messageManager = networkManager.MessageManager;
11351094
var connectionManager = networkManager.ConnectionManager;
11361095

@@ -1170,7 +1129,7 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false
11701129
var message = new NetworkVariableDeltaMessage
11711130
{
11721131
NetworkObjectId = NetworkObjectId,
1173-
NetworkBehaviourIndex = behaviourIndex,
1132+
NetworkBehaviourIndex = NetworkBehaviourId,
11741133
NetworkBehaviour = this,
11751134
TargetClientId = targetClientId,
11761135
DeliveryMappedNetworkVariableIndex = m_DeliveryMappedNetworkVariableIndices[j],
@@ -1608,8 +1567,6 @@ public virtual void OnDestroy()
16081567
{
16091568
networkVar.Dispose();
16101569
}
1611-
1612-
ResetAllFields();
16131570
}
16141571
}
16151572
}

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,7 @@ private bool InternalHasAuthority()
11191119
}
11201120

11211121
/// <summary>
1122-
/// The NetworkManager that owns this NetworkObject.
1123-
/// This property controls where this NetworkObject belongs.
1122+
/// The NetworkManager that is responsible for this NetworkObject instance.
11241123
/// This property is null by default currently, which means that the above NetworkManager getter will return the Singleton.
11251124
/// In the future this is the path where alternative NetworkManagers should be injected for running multi NetworkManagers
11261125
/// </summary>
@@ -1771,6 +1770,9 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
17711770
{
17721771
if (NetworkManagerOwner == null)
17731772
{
1773+
#if TEST_NO_SINGLETON
1774+
Debug.LogError("NetworkObject has no owner client! setting as singleton owner");
1775+
#endif
17741776
NetworkManagerOwner = NetworkManager.Singleton;
17751777
}
17761778
if (!NetworkManager.IsListening)
@@ -1825,7 +1827,7 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
18251827
}
18261828
}
18271829

1828-
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManager.SpawnManager.GetNetworkObjectId(), IsSceneObject.HasValue && IsSceneObject.Value, playerObject, ownerClientId, destroyWithScene);
1830+
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManagerOwner, NetworkManager.SpawnManager.GetNetworkObjectId(), IsSceneObject.HasValue && IsSceneObject.Value, playerObject, ownerClientId, destroyWithScene);
18291831

18301832
if ((NetworkManager.DistributedAuthorityMode && NetworkManager.DAHost) || (!NetworkManager.DistributedAuthorityMode && NetworkManager.IsServer))
18311833
{
@@ -2534,7 +2536,7 @@ internal static void CheckOrphanChildren()
25342536

25352537
internal void InvokeBehaviourNetworkPreSpawn()
25362538
{
2537-
var networkManager = NetworkManager;
2539+
var networkManager = NetworkManagerOwner;
25382540
for (int i = 0; i < ChildNetworkBehaviours.Count; i++)
25392541
{
25402542
if (ChildNetworkBehaviours[i].gameObject.activeInHierarchy)
@@ -2611,58 +2613,74 @@ internal void InvokeBehaviourNetworkDespawn()
26112613
}
26122614
}
26132615

2614-
private List<NetworkBehaviour> m_ChildNetworkBehaviours;
2616+
internal List<NetworkBehaviour> m_ChildNetworkBehaviours;
26152617

26162618
internal List<NetworkBehaviour> ChildNetworkBehaviours
26172619
{
26182620
get
26192621
{
2620-
if (m_ChildNetworkBehaviours != null)
2622+
if (m_ChildNetworkBehaviours == null)
26212623
{
2622-
return m_ChildNetworkBehaviours;
2624+
m_ChildNetworkBehaviours = BuildChildBehavioursList();
26232625
}
26242626

2625-
m_ChildNetworkBehaviours = new List<NetworkBehaviour>();
2626-
var networkBehaviours = GetComponentsInChildren<NetworkBehaviour>(true);
2627-
for (int i = 0; i < networkBehaviours.Length; i++)
2627+
return m_ChildNetworkBehaviours;
2628+
}
2629+
}
2630+
2631+
private List<NetworkBehaviour> BuildChildBehavioursList()
2632+
{
2633+
#if UNITY_EDITOR
2634+
if (NetworkManagerOwner == null)
2635+
{
2636+
Debug.LogError("NetworkManagerOwner should be set! Setting owner to NetworkManager.Singleton");
2637+
NetworkManagerOwner = NetworkManager.Singleton;
2638+
}
2639+
#endif
2640+
2641+
var networkBehaviours = GetComponentsInChildren<NetworkBehaviour>(true);
2642+
var childBehaviours = new List<NetworkBehaviour>(networkBehaviours.Length);
2643+
2644+
foreach (var behaviour in networkBehaviours)
2645+
{
2646+
// Find the first parent NetworkObject of this child
2647+
// if it's not ourselves, this childBehaviour belongs to a different NetworkObject.
2648+
var networkObj = behaviour.GetComponentInParent<NetworkObject>();
2649+
if (networkObj != this)
26282650
{
2629-
// Find the first parent NetworkObject of this child
2630-
// if it's not ourselves, this childBehaviour belongs to a different NetworkObject.
2631-
var networkObj = networkBehaviours[i].GetComponentInParent<NetworkObject>();
2632-
if (networkObj != this)
2633-
{
2634-
continue;
2635-
}
2651+
continue;
2652+
}
26362653

2637-
// Set ourselves as the NetworkObject that this behaviour belongs to and add it to the child list
2638-
networkBehaviours[i].SetNetworkObject(this);
2639-
m_ChildNetworkBehaviours.Add(networkBehaviours[i]);
2654+
// Set ourselves as the NetworkObject that this behaviour belongs to and add it to the child list
2655+
var nextIndex = childBehaviours.Count;
2656+
childBehaviours.Add(behaviour);
2657+
behaviour.SetNetworkObject(this, (ushort)nextIndex);
26402658

2641-
var type = networkBehaviours[i].GetType();
2642-
if (type == typeof(NetworkTransform) || type.IsInstanceOfType(typeof(NetworkTransform)) || type.IsSubclassOf(typeof(NetworkTransform)))
2659+
var type = behaviour.GetType();
2660+
if (type == typeof(NetworkTransform) || type.IsAssignableFrom(typeof(NetworkTransform)) || type.IsSubclassOf(typeof(NetworkTransform)))
2661+
{
2662+
if (NetworkTransforms == null)
26432663
{
2644-
if (NetworkTransforms == null)
2645-
{
2646-
NetworkTransforms = new List<NetworkTransform>();
2647-
}
2648-
var networkTransform = networkBehaviours[i] as NetworkTransform;
2649-
networkTransform.IsNested = i != 0 && networkTransform.gameObject != gameObject;
2650-
NetworkTransforms.Add(networkTransform);
2664+
NetworkTransforms = new List<NetworkTransform>();
26512665
}
2666+
var networkTransform = behaviour as NetworkTransform;
2667+
networkTransform.IsNested = networkTransform.gameObject != gameObject;
2668+
NetworkTransforms.Add(networkTransform);
2669+
}
26522670
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
2653-
else if (type.IsSubclassOf(typeof(NetworkRigidbodyBase)))
2671+
else if (type.IsSubclassOf(typeof(NetworkRigidbodyBase)))
2672+
{
2673+
if (NetworkRigidbodies == null)
26542674
{
2655-
if (NetworkRigidbodies == null)
2656-
{
2657-
NetworkRigidbodies = new List<NetworkRigidbodyBase>();
2658-
}
2659-
NetworkRigidbodies.Add(networkBehaviours[i] as NetworkRigidbodyBase);
2675+
NetworkRigidbodies = new List<NetworkRigidbodyBase>();
26602676
}
2661-
#endif
2677+
NetworkRigidbodies.Add(behaviour as NetworkRigidbodyBase);
26622678
}
2663-
2664-
return m_ChildNetworkBehaviours;
2679+
#endif
26652680
}
2681+
2682+
childBehaviours.TrimExcess();
2683+
return childBehaviours;
26662684
}
26672685

26682686
/// <summary>
@@ -2744,25 +2762,14 @@ internal static void VerifyParentingStatus()
27442762
public ushort GetNetworkBehaviourOrderIndex(NetworkBehaviour instance)
27452763
{
27462764
// read the cached index, and verify it first
2747-
if (instance.NetworkBehaviourIdCache < ChildNetworkBehaviours.Count)
2765+
if (instance.NetworkBehaviourId < ChildNetworkBehaviours.Count)
27482766
{
2749-
if (ChildNetworkBehaviours[instance.NetworkBehaviourIdCache] == instance)
2767+
if (ChildNetworkBehaviours[instance.NetworkBehaviourId] == instance)
27502768
{
2751-
return instance.NetworkBehaviourIdCache;
2769+
return instance.NetworkBehaviourId;
27522770
}
27532771

2754-
// invalid cached id reset
2755-
instance.NetworkBehaviourIdCache = default;
2756-
}
2757-
2758-
for (ushort i = 0; i < ChildNetworkBehaviours.Count; i++)
2759-
{
2760-
if (ChildNetworkBehaviours[i] == instance)
2761-
{
2762-
// cache the id, for next query
2763-
instance.NetworkBehaviourIdCache = i;
2764-
return i;
2765-
}
2772+
Debug.LogError("Network behaviour at index has changed. This should not be possible.");
27662773
}
27672774

27682775
return 0;
@@ -3246,6 +3253,8 @@ internal static NetworkObject AddSceneObject(in SceneObject sceneObject, FastBuf
32463253
return null;
32473254
}
32483255

3256+
networkObject.NetworkManagerOwner = networkManager;
3257+
32493258
// This will get set again when the NetworkObject is spawned locally, but we set it here ahead of spawning
32503259
// in order to be able to determine which NetworkVariables the client will be allowed to read.
32513260
networkObject.OwnerClientId = sceneObject.OwnerClientId;

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1822,7 +1822,7 @@ private void OnSessionOwnerLoadedScene(uint sceneEventId, Scene scene)
18221822
if (!keyValuePairBySceneHandle.Value.IsPlayerObject)
18231823
{
18241824
// All in-scene placed NetworkObjects default to being owned by the server
1825-
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePairBySceneHandle.Value,
1825+
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePairBySceneHandle.Value, NetworkManager,
18261826
NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, NetworkManager.LocalClientId, true);
18271827
}
18281828
}

com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,15 @@ internal void AddDespawnedInSceneNetworkObjects()
376376
#endif
377377
foreach (var sobj in inSceneNetworkObjects)
378378
{
379+
// For integration tests, don't collect objects that don't belong to us.
380+
if (sobj.NetworkManagerOwner != null && sobj.NetworkManagerOwner != m_NetworkManager)
381+
{
382+
continue;
383+
}
384+
379385
if (sobj.IsSceneObject.HasValue && sobj.IsSceneObject.Value && !sobj.IsSpawned)
380386
{
387+
sobj.NetworkManagerOwner = m_NetworkManager;
381388
m_DespawnedInSceneObjectsSync.Add(sobj);
382389
}
383390
}
@@ -1083,19 +1090,22 @@ private void DeserializeDespawnedInScenePlacedNetworkObjects()
10831090
}
10841091

10851092
// Now find the in-scene NetworkObject with the current GlobalObjectIdHash we are looking for
1086-
if (sceneRelativeNetworkObjects.ContainsKey(globalObjectIdHash))
1093+
if (sceneRelativeNetworkObjects.TryGetValue(globalObjectIdHash, out var despawnedObject))
10871094
{
1095+
// Set the owner of this network object
1096+
despawnedObject.NetworkManagerOwner = m_NetworkManager;
1097+
10881098
// Since this is a NetworkObject that was never spawned, we just need to send a notification
10891099
// out that it was despawned so users can make adjustments
1090-
sceneRelativeNetworkObjects[globalObjectIdHash].InvokeBehaviourNetworkDespawn();
1100+
despawnedObject.InvokeBehaviourNetworkDespawn();
10911101
if (!m_NetworkManager.SceneManager.ScenePlacedObjects.ContainsKey(globalObjectIdHash))
10921102
{
10931103
m_NetworkManager.SceneManager.ScenePlacedObjects.Add(globalObjectIdHash, new Dictionary<NetworkSceneHandle, NetworkObject>());
10941104
}
10951105

1096-
if (!m_NetworkManager.SceneManager.ScenePlacedObjects[globalObjectIdHash].ContainsKey(sceneRelativeNetworkObjects[globalObjectIdHash].GetSceneOriginHandle()))
1106+
if (!m_NetworkManager.SceneManager.ScenePlacedObjects[globalObjectIdHash].ContainsKey(despawnedObject.GetSceneOriginHandle()))
10971107
{
1098-
m_NetworkManager.SceneManager.ScenePlacedObjects[globalObjectIdHash].Add(sceneRelativeNetworkObjects[globalObjectIdHash].GetSceneOriginHandle(), sceneRelativeNetworkObjects[globalObjectIdHash]);
1108+
m_NetworkManager.SceneManager.ScenePlacedObjects[globalObjectIdHash].Add(despawnedObject.GetSceneOriginHandle(), despawnedObject);
10991109
}
11001110
}
11011111
else

0 commit comments

Comments
 (0)