Skip to content

Commit d4a6dcc

Browse files
fix: InstantiateAndSpawn not honoring ownerClientId parameter in client-server (#2968)
* fix NetworkSpawnManager.InstantiateAndSpawn should use ownerClientId when not in distributed authority mode. * fix NetworkObject.InstantiateAndSpawn should use ownerClientId when not in distributed authority mode. * test and update Updated NetworkObjectSpawning to validate against InstantiateAndSpawn. Updated ChangeLog entry.
1 parent 8f71c14 commit d4a6dcc

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1212

1313
### Fixed
1414

15+
- Fixed issue where `NetworkSpawnManager.InstantiateAndSpawn` and `NetworkObject.InstantiateAndSpawn` were not honoring the ownerClientId parameter when using a client-server network topology. (#2968)
1516
- Fixed issue where internal delta serialization could not have a byte serializer defined when serializing deltas for other types. Added `[GenerateSerializationForType(typeof(byte))]` to both the `NetworkVariable` and `AnticipatedNetworkVariable` classes to assure a byte serializer is defined.(#2962)
1617
- Fixed issue when scene management was disabled and the session owner would still try to synchronize a late joining client. (#2962)
1718
- Fixed issue when using a distributed authority network topology where it would allow a session owner to spawn a `NetworkObject` prior to being approved. Now, an error message is logged and the `NetworkObject` will not be spawned prior to the client being approved. (#2962)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ public NetworkObject InstantiateAndSpawn(NetworkManager networkManager, ulong ow
16431643
return null;
16441644
}
16451645

1646-
ownerClientId = networkManager.DistributedAuthorityMode ? networkManager.LocalClientId : NetworkManager.ServerClientId;
1646+
ownerClientId = networkManager.DistributedAuthorityMode ? networkManager.LocalClientId : ownerClientId;
16471647
// We only need to check for authority when running in client-server mode
16481648
if (!networkManager.IsServer && !networkManager.DistributedAuthorityMode)
16491649
{

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ public NetworkObject InstantiateAndSpawn(NetworkObject networkPrefab, ulong owne
643643
return null;
644644
}
645645

646-
ownerClientId = NetworkManager.DistributedAuthorityMode ? NetworkManager.LocalClientId : NetworkManager.ServerClientId;
646+
ownerClientId = NetworkManager.DistributedAuthorityMode ? NetworkManager.LocalClientId : ownerClientId;
647647
// We only need to check for authority when running in client-server mode
648648
if (!NetworkManager.IsServer && !NetworkManager.DistributedAuthorityMode)
649649
{

testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,62 @@ public IEnumerator SpawnOnSynchronizedNotification([Values] SynchronizeNotificat
138138
}
139139
}
140140

141+
142+
public enum InstantiateAndSpawnTypes
143+
{
144+
NetworkSpawnManager,
145+
NetworkObject,
146+
}
147+
148+
public enum InstantiateAndSpawnContexts
149+
{
150+
Host,
151+
Client,
152+
}
153+
154+
[UnityTest]
155+
public IEnumerator InstantiateAndSpawn([Values] InstantiateAndSpawnTypes instantiateAndSpawnTypes, [Values] InstantiateAndSpawnContexts instantiateAndSpawnContexts)
156+
{
157+
m_CanStartServerAndClients = true;
158+
Object.DontDestroyOnLoad(m_ObjectToSpawn);
159+
yield return StartServerAndClients();
160+
var instanceNetworkObject = (NetworkObject)null;
161+
// Setup the test relative to parameters driven context
162+
var ownerId = instantiateAndSpawnContexts == InstantiateAndSpawnContexts.Host ? m_ServerNetworkManager.LocalClientId : m_ClientNetworkManagers[0].LocalClientId;
163+
var spawnManager = m_ServerNetworkManager.SpawnManager;
164+
if (m_DistributedAuthority && instantiateAndSpawnContexts == InstantiateAndSpawnContexts.Client)
165+
{
166+
spawnManager = m_ClientNetworkManagers[0].SpawnManager;
167+
}
168+
169+
// Spawn the NetworkObject
170+
if (instantiateAndSpawnTypes == InstantiateAndSpawnTypes.NetworkSpawnManager)
171+
{
172+
Debug.Log($"Spawning {m_ObjectToSpawn.name}");
173+
instanceNetworkObject = spawnManager.InstantiateAndSpawn(m_ObjectToSpawn.GetComponent<NetworkObject>(), ownerId);
174+
}
175+
else
176+
{
177+
instanceNetworkObject = NetworkObject.InstantiateAndSpawn(m_ObjectToSpawn, spawnManager.NetworkManager, ownerId);
178+
}
179+
Assert.IsNotNull(instanceNetworkObject, $"Failed to instantiate {m_ObjectToSpawn.name}!");
180+
Assert.IsTrue(instanceNetworkObject.IsSpawned, $"Failed to spawn {m_ObjectToSpawn.name}!");
181+
Assert.IsTrue(instanceNetworkObject.OwnerClientId == ownerId, $"Invalid owner ({instanceNetworkObject.OwnerClientId} vs {ownerId})!");
182+
yield return WaitForConditionOrTimeOut(() => s_GlobalNetworkObjects.ContainsKey(m_ClientNetworkManagers[0].LocalClientId) && s_GlobalNetworkObjects.ContainsKey(m_ServerNetworkManager.LocalClientId));
183+
AssertOnTimeout($"Timed out waiting for all instances to spawn!");
184+
yield return WaitForConditionOrTimeOut(() => s_GlobalNetworkObjects[m_ClientNetworkManagers[0].LocalClientId].ContainsKey(instanceNetworkObject.NetworkObjectId) && s_GlobalNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(instanceNetworkObject.NetworkObjectId));
185+
AssertOnTimeout($"Timed out waiting for all instances to spawn!");
186+
187+
if (instantiateAndSpawnContexts == InstantiateAndSpawnContexts.Host)
188+
{
189+
Assert.IsTrue(s_GlobalNetworkObjects[m_ClientNetworkManagers[0].LocalClientId].ContainsKey(instanceNetworkObject.NetworkObjectId), $"Client-{m_ClientNetworkManagers[0].LocalClientId} failed to spawn {instanceNetworkObject.name}!");
190+
}
191+
else
192+
{
193+
Assert.IsTrue(s_GlobalNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(instanceNetworkObject.NetworkObjectId), $"Client-{m_ServerNetworkManager.LocalClientId} failed to spawn {instanceNetworkObject.name}!");
194+
}
195+
}
196+
141197
private void SceneLoaded(Scene scene, LoadSceneMode arg1)
142198
{
143199
if (scene.name == k_SceneToLoad)

0 commit comments

Comments
 (0)