Skip to content

Commit b73d06b

Browse files
committed
Ensure NetworkManagerOwner is always correctly set
1 parent e85dd74 commit b73d06b

File tree

9 files changed

+101
-146
lines changed

9 files changed

+101
-146
lines changed

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
@@ -546,9 +546,10 @@ internal bool IsBehaviourEditable()
546546
return HasAuthority;
547547
}
548548

549-
internal void SetNetworkObject(NetworkObject networkObject)
549+
internal void SetNetworkObject(NetworkObject networkObject, ushort behaviourId)
550550
{
551551
m_NetworkObject = networkObject;
552+
NetworkBehaviourId = behaviourId;
552553
}
553554

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

616-
/// <summary>
617-
/// Internally caches the Id of this behaviour in a NetworkObject. Makes look-up faster
618-
/// </summary>
619-
internal ushort NetworkBehaviourIdCache = 0;
620-
621617
/// <summary>
622618
/// Returns the NetworkBehaviour with a given BehaviourId for the current NetworkObject.
623619
/// </summary>
@@ -647,11 +643,6 @@ internal void UpdateNetworkProperties()
647643
NetworkObjectId = networkObject.NetworkObjectId;
648644
IsLocalPlayer = networkObject.IsLocalPlayer;
649645

650-
// This is "OK" because GetNetworkBehaviourOrderIndex uses the order of
651-
// NetworkObject.ChildNetworkBehaviours which is set once when first
652-
// accessed.
653-
NetworkBehaviourId = networkObject.GetNetworkBehaviourOrderIndex(this);
654-
655646
// Set ownership related properties
656647
IsOwnedByServer = networkObject.IsOwnedByServer;
657648
IsOwner = networkObject.IsOwner;
@@ -669,35 +660,6 @@ internal void UpdateNetworkProperties()
669660
}
670661
}
671662

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

897857
/// <summary>
@@ -1128,7 +1088,6 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false
11281088
// Getting these ahead of time actually improves performance
11291089
var networkManager = m_NetworkManager;
11301090
var networkObject = m_NetworkObject;
1131-
var behaviourIndex = networkObject.GetNetworkBehaviourOrderIndex(this);
11321091
var messageManager = networkManager.MessageManager;
11331092
var connectionManager = networkManager.ConnectionManager;
11341093

@@ -1168,7 +1127,7 @@ internal void NetworkVariableUpdate(ulong targetClientId, bool forceSend = false
11681127
var message = new NetworkVariableDeltaMessage
11691128
{
11701129
NetworkObjectId = NetworkObjectId,
1171-
NetworkBehaviourIndex = behaviourIndex,
1130+
NetworkBehaviourIndex = NetworkBehaviourId,
11721131
NetworkBehaviour = this,
11731132
TargetClientId = targetClientId,
11741133
DeliveryMappedNetworkVariableIndex = m_DeliveryMappedNetworkVariableIndices[j],
@@ -1606,8 +1565,6 @@ public virtual void OnDestroy()
16061565
{
16071566
networkVar.Dispose();
16081567
}
1609-
1610-
ResetAllFields();
16111568
}
16121569
}
16131570
}

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)