private void SpawnInternal(Stream spawnPayload, bool destroyWithScene, ulong?ownerClientId, bool playerObject) { if (!NetworkManager.Singleton.IsListening) { throw new NotListeningException($"{nameof(NetworkManager)} isn't listening, start a server or host before spawning objects."); } if (!NetworkManager.Singleton.IsServer) { throw new NotServerException($"Only server can spawn {nameof(NetworkObject)}s"); } if (spawnPayload != null) { spawnPayload.Position = 0; } NetworkSpawnManager.SpawnNetworkObjectLocally(this, NetworkSpawnManager.GetNetworkObjectId(), false, playerObject, ownerClientId, spawnPayload, spawnPayload != null, spawnPayload == null ? 0 : (int)spawnPayload.Length, false, destroyWithScene); for (int i = 0; i < NetworkManager.Singleton.ConnectedClientsList.Count; i++) { if (m_Observers.Contains(NetworkManager.Singleton.ConnectedClientsList[i].ClientId)) { NetworkSpawnManager.SendSpawnCallForObject(NetworkManager.Singleton.ConnectedClientsList[i].ClientId, this, spawnPayload); } } }
private static void OnSceneUnloadServer(Guid switchSceneGuid) { // Justification: Rare alloc, could(should?) reuse var newSceneObjects = new List <NetworkObject>(); { var networkObjects = MonoBehaviour.FindObjectsOfType <NetworkObject>(); for (int i = 0; i < networkObjects.Length; i++) { if (networkObjects[i].IsSceneObject == null) { NetworkSpawnManager.SpawnNetworkObjectLocally(networkObjects[i], NetworkSpawnManager.GetNetworkObjectId(), true, false, null, null, false, 0, false, true); newSceneObjects.Add(networkObjects[i]); } } } for (int j = 0; j < NetworkManager.Singleton.ConnectedClientsList.Count; j++) { if (NetworkManager.Singleton.ConnectedClientsList[j].ClientId != NetworkManager.Singleton.ServerClientId) { using (var buffer = PooledNetworkBuffer.Get()) using (var writer = PooledNetworkWriter.Get(buffer)) { writer.WriteUInt32Packed(CurrentActiveSceneIndex); writer.WriteByteArray(switchSceneGuid.ToByteArray()); uint sceneObjectsToSpawn = 0; for (int i = 0; i < newSceneObjects.Count; i++) { if (newSceneObjects[i].m_Observers.Contains(NetworkManager.Singleton.ConnectedClientsList[j].ClientId)) { sceneObjectsToSpawn++; } } writer.WriteUInt32Packed(sceneObjectsToSpawn); for (int i = 0; i < newSceneObjects.Count; i++) { if (newSceneObjects[i].m_Observers.Contains(NetworkManager.Singleton.ConnectedClientsList[j].ClientId)) { writer.WriteBool(newSceneObjects[i].IsPlayerObject); writer.WriteUInt64Packed(newSceneObjects[i].NetworkObjectId); writer.WriteUInt64Packed(newSceneObjects[i].OwnerClientId); NetworkObject parentNetworkObject = null; if (!newSceneObjects[i].AlwaysReplicateAsRoot && newSceneObjects[i].transform.parent != null) { parentNetworkObject = newSceneObjects[i].transform.parent.GetComponent <NetworkObject>(); } if (parentNetworkObject == null) { writer.WriteBool(false); } else { writer.WriteBool(true); writer.WriteUInt64Packed(parentNetworkObject.NetworkObjectId); } if (!NetworkManager.Singleton.NetworkConfig.EnableSceneManagement || NetworkManager.Singleton.NetworkConfig.UsePrefabSync) { writer.WriteUInt64Packed(newSceneObjects[i].PrefabHash); writer.WriteSinglePacked(newSceneObjects[i].transform.position.x); writer.WriteSinglePacked(newSceneObjects[i].transform.position.y); writer.WriteSinglePacked(newSceneObjects[i].transform.position.z); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.x); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.y); writer.WriteSinglePacked(newSceneObjects[i].transform.rotation.eulerAngles.z); } else { writer.WriteUInt64Packed(newSceneObjects[i].NetworkInstanceId); } if (NetworkManager.Singleton.NetworkConfig.EnableNetworkVariable) { newSceneObjects[i].WriteNetworkVariableData(buffer, NetworkManager.Singleton.ConnectedClientsList[j].ClientId); } } } InternalMessageSender.Send(NetworkManager.Singleton.ConnectedClientsList[j].ClientId, NetworkConstants.SWITCH_SCENE, NetworkChannel.Internal, buffer); } } } //Tell server that scene load is completed if (NetworkManager.Singleton.IsHost) { OnClientSwitchSceneCompleted(NetworkManager.Singleton.LocalClientId, switchSceneGuid); } s_IsSwitching = false; OnSceneSwitched?.Invoke(); }