com.unity.netcode.gameobjects@1.5.1
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). ## [1.5.1] - 2023-06-07 ### Added - Added support for serializing `NativeArray<>` and `NativeList<>` in `FastBufferReader`/`FastBufferWriter`, `BufferSerializer`, `NetworkVariable`, and RPCs. (To use `NativeList<>`, add `UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT` to your Scripting Define Symbols in `Project Settings > Player`) (#2375) - The location of the automatically-created default network prefab list can now be configured (#2544) - Added: Message size limits (max single message and max fragmented message) can now be set using NetworkManager.MaximumTransmissionUnitSize and NetworkManager.MaximumFragmentedMessageSize for transports that don't work with the default values (#2530) - Added `NetworkObject.SpawnWithObservers` property (default is true) that when set to false will spawn a `NetworkObject` with no observers and will not be spawned on any client until `NetworkObject.NetworkShow` is invoked. (#2568) ### Fixed - Fixed: Fixed a null reference in codegen in some projects (#2581) - Fixed issue where the `OnClientDisconnected` client identifier was incorrect after a pending client connection was denied. (#2569) - Fixed warning "Runtime Network Prefabs was not empty at initialization time." being erroneously logged when no runtime network prefabs had been added (#2565) - Fixed issue where some temporary debug console logging was left in a merged PR. (#2562) - Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545) - Fixed issue where users could not use NetworkSceneManager.VerifySceneBeforeLoading to exclude runtime generated scenes from client synchronization. (#2550) - Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events. (#2542,#2543) - Fixed issue where parenting a NetworkTransform under a transform with a scale other than Vector3.one would result in incorrect values on non-authoritative instances. (#2538) - Fixed issue where a server would include scene migrated and then despawned NetworkObjects to a client that was being synchronized. (#2532) - Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529) - Making a `NetworkVariable` with an `INetworkSerializable` type that doesn't meet the `new()` constraint will now create a compile-time error instead of an editor crash (#2528) - Fixed Multiplayer Tools package installation docs page link on the NetworkManager popup. (#2526) - Fixed an exception and error logging when two different objects are shown and hidden on the same frame (#2524) - Fixed a memory leak in `UnityTransport` that occurred if `StartClient` failed. (#2518) - Fixed issue where a client could throw an exception if abruptly disconnected from a network session with one or more spawned `NetworkObject`(s). (#2510) - Fixed issue where invalid endpoint addresses were not being detected and returning false from NGO UnityTransport. (#2496) - Fixed some errors that could occur if a connection is lost and the loss is detected when attempting to write to the socket. (#2495) ## Changed - Adding network prefabs before NetworkManager initialization is now supported. (#2565) - Connecting clients being synchronized now switch to the server's active scene before spawning and synchronizing NetworkObjects. (#2532) - Updated `UnityTransport` dependency on `com.unity.transport` to 1.3.4. (#2533) - Improved performance of NetworkBehaviour initialization by replacing reflection when initializing NetworkVariables with compile-time code generation, which should help reduce hitching during additive scene loads. (#2522)
This commit is contained in:
@@ -337,7 +337,7 @@ namespace Unity.Netcode
|
||||
return;
|
||||
}
|
||||
else // Warn users if they are changing this after there are clients already connected and synchronized
|
||||
if (networkManager.ConnectedClientsIds.Count > (networkManager.IsServer ? 0 : 1) && sceneManager.ClientSynchronizationMode != mode)
|
||||
if (networkManager.ConnectedClientsIds.Count > (networkManager.IsHost ? 1 : 0) && sceneManager.ClientSynchronizationMode != mode)
|
||||
{
|
||||
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
|
||||
{
|
||||
|
||||
@@ -524,7 +524,7 @@ namespace Unity.Netcode
|
||||
/// </summary>
|
||||
internal Dictionary<uint, SceneEventData> SceneEventDataStore;
|
||||
|
||||
private NetworkManager m_NetworkManager { get; }
|
||||
internal readonly NetworkManager NetworkManager;
|
||||
|
||||
// Keep track of this scene until the NetworkSceneManager is destroyed.
|
||||
internal Scene DontDestroyOnLoadScene;
|
||||
@@ -575,7 +575,7 @@ namespace Unity.Netcode
|
||||
/// <returns>SceneEventData instance</returns>
|
||||
internal SceneEventData BeginSceneEvent()
|
||||
{
|
||||
var sceneEventData = new SceneEventData(m_NetworkManager);
|
||||
var sceneEventData = new SceneEventData(NetworkManager);
|
||||
SceneEventDataStore.Add(sceneEventData.SceneEventId, sceneEventData);
|
||||
return sceneEventData;
|
||||
}
|
||||
@@ -720,18 +720,18 @@ namespace Unity.Netcode
|
||||
/// <param name="mode"><see cref="LoadSceneMode"/> for initial client synchronization</param>
|
||||
public void SetClientSynchronizationMode(LoadSceneMode mode)
|
||||
{
|
||||
var networkManager = m_NetworkManager;
|
||||
var networkManager = NetworkManager;
|
||||
SceneManagerHandler.SetClientSynchronizationMode(ref networkManager, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="networkManager">one <see cref="NetworkManager"/> instance per <see cref="NetworkSceneManager"/> instance</param>
|
||||
/// <param name="networkManager">one <see cref="Netcode.NetworkManager"/> instance per <see cref="NetworkSceneManager"/> instance</param>
|
||||
/// <param name="sceneEventDataPoolSize">maximum <see cref="SceneEventData"/> pool size</param>
|
||||
internal NetworkSceneManager(NetworkManager networkManager)
|
||||
{
|
||||
m_NetworkManager = networkManager;
|
||||
NetworkManager = networkManager;
|
||||
SceneEventDataStore = new Dictionary<uint, SceneEventData>();
|
||||
|
||||
// Generates the scene name to hash value
|
||||
@@ -750,7 +750,7 @@ namespace Unity.Netcode
|
||||
private void SceneManager_ActiveSceneChanged(Scene current, Scene next)
|
||||
{
|
||||
// If no clients are connected, then don't worry about notifications
|
||||
if (!(m_NetworkManager.ConnectedClientsIds.Count > (m_NetworkManager.IsHost ? 1 : 0)))
|
||||
if (!(NetworkManager.ConnectedClientsIds.Count > (NetworkManager.IsHost ? 1 : 0)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -771,7 +771,7 @@ namespace Unity.Netcode
|
||||
var sceneEvent = BeginSceneEvent();
|
||||
sceneEvent.SceneEventType = SceneEventType.ActiveSceneChanged;
|
||||
sceneEvent.ActiveSceneHash = BuildIndexToHash[next.buildIndex];
|
||||
SendSceneEventData(sceneEvent.SceneEventId, m_NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
SendSceneEventData(sceneEvent.SceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
EndSceneEvent(sceneEvent.SceneEventId);
|
||||
}
|
||||
}
|
||||
@@ -786,9 +786,18 @@ namespace Unity.Netcode
|
||||
/// <returns>true (Valid) or false (Invalid)</returns>
|
||||
internal bool ValidateSceneBeforeLoading(uint sceneHash, LoadSceneMode loadSceneMode)
|
||||
{
|
||||
var validated = true;
|
||||
var sceneName = SceneNameFromHash(sceneHash);
|
||||
var sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneName);
|
||||
return ValidateSceneBeforeLoading(sceneIndex, sceneName, loadSceneMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overloaded version that is invoked by <see cref="ValidateSceneBeforeLoading"/> and <see cref="SynchronizeNetworkObjects"/>.
|
||||
/// This specifically is to allow runtime generated scenes to be excluded by the server during synchronization.
|
||||
/// </summary>
|
||||
internal bool ValidateSceneBeforeLoading(int sceneIndex, string sceneName, LoadSceneMode loadSceneMode)
|
||||
{
|
||||
var validated = true;
|
||||
if (VerifySceneBeforeLoading != null)
|
||||
{
|
||||
validated = VerifySceneBeforeLoading.Invoke(sceneIndex, sceneName, loadSceneMode);
|
||||
@@ -796,9 +805,9 @@ namespace Unity.Netcode
|
||||
if (!validated && !m_DisableValidationWarningMessages)
|
||||
{
|
||||
var serverHostorClient = "Client";
|
||||
if (m_NetworkManager.IsServer)
|
||||
if (NetworkManager.IsServer)
|
||||
{
|
||||
serverHostorClient = m_NetworkManager.IsHost ? "Host" : "Server";
|
||||
serverHostorClient = NetworkManager.IsHost ? "Host" : "Server";
|
||||
}
|
||||
|
||||
Debug.LogWarning($"Scene {sceneName} of Scenes in Build Index {sceneIndex} being loaded in {loadSceneMode} mode failed validation on the {serverHostorClient}!");
|
||||
@@ -837,7 +846,7 @@ namespace Unity.Netcode
|
||||
if (!ScenesLoaded.ContainsKey(sceneLoaded.handle))
|
||||
{
|
||||
ScenesLoaded.Add(sceneLoaded.handle, sceneLoaded);
|
||||
SceneManagerHandler.StartTrackingScene(sceneLoaded, true, m_NetworkManager);
|
||||
SceneManagerHandler.StartTrackingScene(sceneLoaded, true, NetworkManager);
|
||||
return sceneLoaded;
|
||||
}
|
||||
}
|
||||
@@ -886,7 +895,7 @@ namespace Unity.Netcode
|
||||
// Most common scenario for DontDestroyOnLoad is when NetworkManager is set to not be destroyed
|
||||
if (serverSceneHandle == DontDestroyOnLoadScene.handle)
|
||||
{
|
||||
SceneBeingSynchronized = m_NetworkManager.gameObject.scene;
|
||||
SceneBeingSynchronized = NetworkManager.gameObject.scene;
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -940,9 +949,9 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = SceneEventDataStore[sceneEventId]
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, targetClientIds);
|
||||
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, targetClientIds);
|
||||
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(targetClientIds, (uint)SceneEventDataStore[sceneEventId].SceneEventType, SceneNameFromHash(SceneEventDataStore[sceneEventId].SceneHash), size);
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventSent(targetClientIds, (uint)SceneEventDataStore[sceneEventId].SceneEventType, SceneNameFromHash(SceneEventDataStore[sceneEventId].SceneHash), size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -952,16 +961,16 @@ namespace Unity.Netcode
|
||||
/// <returns></returns>
|
||||
private SceneEventProgress ValidateSceneEventUnloading(Scene scene)
|
||||
{
|
||||
if (!m_NetworkManager.IsServer)
|
||||
if (!NetworkManager.IsServer)
|
||||
{
|
||||
throw new NotServerException("Only server can start a scene event!");
|
||||
}
|
||||
|
||||
if (!m_NetworkManager.NetworkConfig.EnableSceneManagement)
|
||||
if (!NetworkManager.NetworkConfig.EnableSceneManagement)
|
||||
{
|
||||
//Log message about enabling SceneManagement
|
||||
throw new Exception(
|
||||
$"{nameof(NetworkConfig.EnableSceneManagement)} flag is not enabled in the {nameof(NetworkManager)}'s {nameof(NetworkConfig)}. " +
|
||||
$"{nameof(NetworkConfig.EnableSceneManagement)} flag is not enabled in the {nameof(Netcode.NetworkManager)}'s {nameof(NetworkConfig)}. " +
|
||||
$"Please set {nameof(NetworkConfig.EnableSceneManagement)} flag to true before calling {nameof(LoadScene)} or {nameof(UnloadScene)}.");
|
||||
}
|
||||
|
||||
@@ -981,15 +990,15 @@ namespace Unity.Netcode
|
||||
/// <returns></returns>
|
||||
private SceneEventProgress ValidateSceneEventLoading(string sceneName)
|
||||
{
|
||||
if (!m_NetworkManager.IsServer)
|
||||
if (!NetworkManager.IsServer)
|
||||
{
|
||||
throw new NotServerException("Only server can start a scene event!");
|
||||
}
|
||||
if (!m_NetworkManager.NetworkConfig.EnableSceneManagement)
|
||||
if (!NetworkManager.NetworkConfig.EnableSceneManagement)
|
||||
{
|
||||
//Log message about enabling SceneManagement
|
||||
throw new Exception(
|
||||
$"{nameof(NetworkConfig.EnableSceneManagement)} flag is not enabled in the {nameof(NetworkManager)}'s {nameof(NetworkConfig)}. " +
|
||||
$"{nameof(NetworkConfig.EnableSceneManagement)} flag is not enabled in the {nameof(Netcode.NetworkManager)}'s {nameof(NetworkConfig)}. " +
|
||||
$"Please set {nameof(NetworkConfig.EnableSceneManagement)} flag to true before calling {nameof(LoadScene)} or {nameof(UnloadScene)}.");
|
||||
}
|
||||
|
||||
@@ -1017,7 +1026,7 @@ namespace Unity.Netcode
|
||||
return new SceneEventProgress(null, SceneEventProgressStatus.InvalidSceneName);
|
||||
}
|
||||
|
||||
var sceneEventProgress = new SceneEventProgress(m_NetworkManager)
|
||||
var sceneEventProgress = new SceneEventProgress(NetworkManager)
|
||||
{
|
||||
SceneHash = SceneHashFromNameOrPath(sceneName)
|
||||
};
|
||||
@@ -1052,10 +1061,10 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = sceneEventData
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, m_NetworkManager.ConnectedClientsIds);
|
||||
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ConnectedClientsIds);
|
||||
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(
|
||||
m_NetworkManager.ConnectedClientsIds,
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventSent(
|
||||
NetworkManager.ConnectedClientsIds,
|
||||
(uint)sceneEventProgress.SceneEventType,
|
||||
SceneNameFromHash(sceneEventProgress.SceneHash),
|
||||
size);
|
||||
@@ -1116,7 +1125,7 @@ namespace Unity.Netcode
|
||||
// Any NetworkObjects marked to not be destroyed with a scene and reside within the scene about to be unloaded
|
||||
// should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
|
||||
// currently active scene.
|
||||
var networkManager = m_NetworkManager;
|
||||
var networkManager = NetworkManager;
|
||||
SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene);
|
||||
|
||||
var sceneEventData = BeginSceneEvent();
|
||||
@@ -1179,18 +1188,18 @@ namespace Unity.Netcode
|
||||
// Any NetworkObjects marked to not be destroyed with a scene and reside within the scene about to be unloaded
|
||||
// should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
|
||||
// currently active scene.
|
||||
var networkManager = m_NetworkManager;
|
||||
var networkManager = NetworkManager;
|
||||
SceneManagerHandler.MoveObjectsFromSceneToDontDestroyOnLoad(ref networkManager, scene);
|
||||
|
||||
m_IsSceneEventActive = true;
|
||||
var sceneEventProgress = new SceneEventProgress(m_NetworkManager)
|
||||
var sceneEventProgress = new SceneEventProgress(NetworkManager)
|
||||
{
|
||||
SceneEventId = sceneEventData.SceneEventId,
|
||||
OnSceneEventCompleted = OnSceneUnloaded
|
||||
};
|
||||
var sceneUnload = SceneManagerHandler.UnloadSceneAsync(scene, sceneEventProgress);
|
||||
|
||||
SceneManagerHandler.StopTrackingScene(sceneHandle, sceneName, m_NetworkManager);
|
||||
SceneManagerHandler.StopTrackingScene(sceneHandle, sceneName, NetworkManager);
|
||||
|
||||
// Remove our server to scene handle lookup
|
||||
if (!RemoveServerClientSceneHandle(sceneEventData.SceneHandle, sceneHandle))
|
||||
@@ -1206,10 +1215,10 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = LoadSceneMode.Additive, // The only scenes unloaded are scenes that were additively loaded
|
||||
SceneName = sceneName,
|
||||
ClientId = m_NetworkManager.LocalClientId // Server sent this message to the client, but client is executing it
|
||||
ClientId = NetworkManager.LocalClientId // Server sent this message to the client, but client is executing it
|
||||
});
|
||||
|
||||
OnUnload?.Invoke(m_NetworkManager.LocalClientId, sceneName, sceneUnload);
|
||||
OnUnload?.Invoke(NetworkManager.LocalClientId, sceneName, sceneUnload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1219,7 +1228,7 @@ namespace Unity.Netcode
|
||||
private void OnSceneUnloaded(uint sceneEventId)
|
||||
{
|
||||
// If we are shutdown or about to shutdown, then ignore this event
|
||||
if (!m_NetworkManager.IsListening || m_NetworkManager.ShutdownInProgress)
|
||||
if (!NetworkManager.IsListening || NetworkManager.ShutdownInProgress)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1229,15 +1238,15 @@ namespace Unity.Netcode
|
||||
|
||||
var sceneEventData = SceneEventDataStore[sceneEventId];
|
||||
// First thing we do, if we are a server, is to send the unload scene event.
|
||||
if (m_NetworkManager.IsServer)
|
||||
if (NetworkManager.IsServer)
|
||||
{
|
||||
// Server sends the unload scene notification after unloading because it will despawn all scene relative in-scene NetworkObjects
|
||||
// If we send this event to all clients before the server is finished unloading they will get warning about an object being
|
||||
// despawned that no longer exists
|
||||
SendSceneEventData(sceneEventId, m_NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
SendSceneEventData(sceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
|
||||
//Only if we are a host do we want register having loaded for the associated SceneEventProgress
|
||||
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && m_NetworkManager.IsHost)
|
||||
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && NetworkManager.IsHost)
|
||||
{
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].ClientFinishedSceneEvent(NetworkManager.ServerClientId);
|
||||
}
|
||||
@@ -1252,13 +1261,13 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
|
||||
ClientId = m_NetworkManager.IsServer ? NetworkManager.ServerClientId : m_NetworkManager.LocalClientId
|
||||
ClientId = NetworkManager.IsServer ? NetworkManager.ServerClientId : NetworkManager.LocalClientId
|
||||
});
|
||||
|
||||
OnUnloadComplete?.Invoke(m_NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash));
|
||||
OnUnloadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash));
|
||||
|
||||
// Clients send a notification back to the server they have completed the unload scene event
|
||||
if (!m_NetworkManager.IsServer)
|
||||
if (!NetworkManager.IsServer)
|
||||
{
|
||||
SendSceneEventData(sceneEventId, new ulong[] { NetworkManager.ServerClientId });
|
||||
}
|
||||
@@ -1288,7 +1297,7 @@ namespace Unity.Netcode
|
||||
// Validate the scene as well as ignore the DDOL (which will have a negative buildIndex)
|
||||
if (currentActiveScene.name != keyHandleEntry.Value.name && keyHandleEntry.Value.buildIndex >= 0)
|
||||
{
|
||||
var sceneEventProgress = new SceneEventProgress(m_NetworkManager)
|
||||
var sceneEventProgress = new SceneEventProgress(NetworkManager)
|
||||
{
|
||||
SceneEventId = sceneEventId,
|
||||
OnSceneEventCompleted = EmptySceneUnloadedOperation
|
||||
@@ -1299,7 +1308,7 @@ namespace Unity.Netcode
|
||||
}
|
||||
// clear out our scenes loaded list
|
||||
ScenesLoaded.Clear();
|
||||
SceneManagerHandler.ClearSceneTracking(m_NetworkManager);
|
||||
SceneManagerHandler.ClearSceneTracking(NetworkManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1348,7 +1357,7 @@ namespace Unity.Netcode
|
||||
IsSpawnedObjectsPendingInDontDestroyOnLoad = true;
|
||||
|
||||
// Destroy current scene objects before switching.
|
||||
m_NetworkManager.SpawnManager.ServerDestroySpawnedSceneObjects();
|
||||
NetworkManager.SpawnManager.ServerDestroySpawnedSceneObjects();
|
||||
|
||||
// Preserve the objects that should not be destroyed during the scene event
|
||||
MoveObjectsToDontDestroyOnLoad();
|
||||
@@ -1390,7 +1399,7 @@ namespace Unity.Netcode
|
||||
|
||||
internal static void RegisterScene(NetworkSceneManager networkSceneManager, Scene scene, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation = null)
|
||||
{
|
||||
var networkManager = networkSceneManager.m_NetworkManager;
|
||||
var networkManager = networkSceneManager.NetworkManager;
|
||||
if (!s_Instances.ContainsKey(networkManager))
|
||||
{
|
||||
s_Instances.Add(networkManager, new List<SceneUnloadEventHandler>());
|
||||
@@ -1401,11 +1410,11 @@ namespace Unity.Netcode
|
||||
|
||||
private static void SceneUnloadComplete(SceneUnloadEventHandler sceneUnloadEventHandler)
|
||||
{
|
||||
if (sceneUnloadEventHandler == null || sceneUnloadEventHandler.m_NetworkSceneManager == null || sceneUnloadEventHandler.m_NetworkSceneManager.m_NetworkManager == null)
|
||||
if (sceneUnloadEventHandler == null || sceneUnloadEventHandler.m_NetworkSceneManager == null || sceneUnloadEventHandler.m_NetworkSceneManager.NetworkManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var networkManager = sceneUnloadEventHandler.m_NetworkSceneManager.m_NetworkManager;
|
||||
var networkManager = sceneUnloadEventHandler.m_NetworkSceneManager.NetworkManager;
|
||||
if (s_Instances.ContainsKey(networkManager))
|
||||
{
|
||||
s_Instances[networkManager].Remove(sceneUnloadEventHandler);
|
||||
@@ -1449,7 +1458,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
if (m_Scene.handle == scene.handle && !m_ShuttingDown)
|
||||
{
|
||||
if (m_NetworkSceneManager != null && m_NetworkSceneManager.m_NetworkManager != null)
|
||||
if (m_NetworkSceneManager != null && m_NetworkSceneManager.NetworkManager != null)
|
||||
{
|
||||
m_NetworkSceneManager.OnSceneEvent?.Invoke(new SceneEvent()
|
||||
{
|
||||
@@ -1484,7 +1493,7 @@ namespace Unity.Netcode
|
||||
ClientId = clientId
|
||||
});
|
||||
|
||||
m_NetworkSceneManager.OnUnload?.Invoke(networkSceneManager.m_NetworkManager.LocalClientId, m_Scene.name, null);
|
||||
m_NetworkSceneManager.OnUnload?.Invoke(networkSceneManager.NetworkManager.LocalClientId, m_Scene.name, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1527,7 +1536,7 @@ namespace Unity.Netcode
|
||||
SceneUnloadEventHandler.RegisterScene(this, SceneManager.GetActiveScene(), LoadSceneMode.Single);
|
||||
|
||||
}
|
||||
var sceneEventProgress = new SceneEventProgress(m_NetworkManager)
|
||||
var sceneEventProgress = new SceneEventProgress(NetworkManager)
|
||||
{
|
||||
SceneEventId = sceneEventId,
|
||||
OnSceneEventCompleted = OnSceneLoaded
|
||||
@@ -1540,10 +1549,10 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = sceneName,
|
||||
ClientId = m_NetworkManager.LocalClientId
|
||||
ClientId = NetworkManager.LocalClientId
|
||||
});
|
||||
|
||||
OnLoad?.Invoke(m_NetworkManager.LocalClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
|
||||
OnLoad?.Invoke(NetworkManager.LocalClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1553,7 +1562,7 @@ namespace Unity.Netcode
|
||||
private void OnSceneLoaded(uint sceneEventId)
|
||||
{
|
||||
// If we are shutdown or about to shutdown, then ignore this event
|
||||
if (!m_NetworkManager.IsListening || m_NetworkManager.ShutdownInProgress)
|
||||
if (!NetworkManager.IsListening || NetworkManager.ShutdownInProgress)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1586,7 +1595,7 @@ namespace Unity.Netcode
|
||||
// not destroy temporary scene are moved into the active scene
|
||||
IsSpawnedObjectsPendingInDontDestroyOnLoad = false;
|
||||
|
||||
if (m_NetworkManager.IsServer)
|
||||
if (NetworkManager.IsServer)
|
||||
{
|
||||
OnServerLoadedScene(sceneEventId, nextScene);
|
||||
}
|
||||
@@ -1618,8 +1627,8 @@ namespace Unity.Netcode
|
||||
if (!keyValuePairBySceneHandle.Value.IsPlayerObject)
|
||||
{
|
||||
// All in-scene placed NetworkObjects default to being owned by the server
|
||||
m_NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePairBySceneHandle.Value,
|
||||
m_NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, NetworkManager.ServerClientId, true);
|
||||
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePairBySceneHandle.Value,
|
||||
NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, NetworkManager.ServerClientId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1631,9 +1640,9 @@ namespace Unity.Netcode
|
||||
sceneEventData.SceneHandle = scene.handle;
|
||||
|
||||
// Send all clients the scene load event
|
||||
for (int j = 0; j < m_NetworkManager.ConnectedClientsList.Count; j++)
|
||||
for (int j = 0; j < NetworkManager.ConnectedClientsList.Count; j++)
|
||||
{
|
||||
var clientId = m_NetworkManager.ConnectedClientsList[j].ClientId;
|
||||
var clientId = NetworkManager.ConnectedClientsList[j].ClientId;
|
||||
if (clientId != NetworkManager.ServerClientId)
|
||||
{
|
||||
sceneEventData.TargetClientId = clientId;
|
||||
@@ -1641,8 +1650,8 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = sceneEventData
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, clientId);
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEventData.SceneEventType, scene.name, size);
|
||||
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, clientId);
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEventData.SceneEventType, scene.name, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1660,7 +1669,7 @@ namespace Unity.Netcode
|
||||
OnLoadComplete?.Invoke(NetworkManager.ServerClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
|
||||
|
||||
//Second, only if we are a host do we want register having loaded for the associated SceneEventProgress
|
||||
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && m_NetworkManager.IsHost)
|
||||
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && NetworkManager.IsHost)
|
||||
{
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].ClientFinishedSceneEvent(NetworkManager.ServerClientId);
|
||||
}
|
||||
@@ -1686,11 +1695,11 @@ namespace Unity.Netcode
|
||||
SceneEventType = SceneEventType.LoadComplete,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
|
||||
ClientId = m_NetworkManager.LocalClientId,
|
||||
ClientId = NetworkManager.LocalClientId,
|
||||
Scene = scene,
|
||||
});
|
||||
|
||||
OnLoadComplete?.Invoke(m_NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
|
||||
OnLoadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
|
||||
|
||||
EndSceneEvent(sceneEventId);
|
||||
}
|
||||
@@ -1713,7 +1722,7 @@ namespace Unity.Netcode
|
||||
internal void SynchronizeNetworkObjects(ulong clientId)
|
||||
{
|
||||
// Update the clients
|
||||
m_NetworkManager.SpawnManager.UpdateObservedNetworkObjects(clientId);
|
||||
NetworkManager.SpawnManager.UpdateObservedNetworkObjects(clientId);
|
||||
|
||||
var sceneEventData = BeginSceneEvent();
|
||||
sceneEventData.ClientSynchronizationMode = ClientSynchronizationMode;
|
||||
@@ -1744,24 +1753,22 @@ namespace Unity.Netcode
|
||||
continue;
|
||||
}
|
||||
|
||||
var sceneHash = SceneHashFromNameOrPath(scene.path);
|
||||
|
||||
// This would depend upon whether we are additive or not
|
||||
// If we are the base scene, then we set the root scene index;
|
||||
if (activeScene == scene)
|
||||
{
|
||||
if (!ValidateSceneBeforeLoading(sceneHash, sceneEventData.LoadSceneMode))
|
||||
if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, sceneEventData.LoadSceneMode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sceneEventData.SceneHash = sceneHash;
|
||||
sceneEventData.SceneHash = SceneHashFromNameOrPath(scene.path);
|
||||
sceneEventData.SceneHandle = scene.handle;
|
||||
}
|
||||
else if (!ValidateSceneBeforeLoading(sceneHash, LoadSceneMode.Additive))
|
||||
else if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, LoadSceneMode.Additive))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sceneEventData.AddSceneToSynchronize(sceneHash, scene.handle);
|
||||
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), scene.handle);
|
||||
}
|
||||
|
||||
sceneEventData.AddSpawnedNetworkObjects();
|
||||
@@ -1771,8 +1778,8 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = sceneEventData
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, clientId);
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEventData.SceneEventType, "", size);
|
||||
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, clientId);
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventSent(clientId, (uint)sceneEventData.SceneEventType, "", size);
|
||||
|
||||
// Notify the local server that the client has been sent the synchronize event
|
||||
OnSceneEvent?.Invoke(new SceneEvent()
|
||||
@@ -1811,17 +1818,17 @@ namespace Unity.Netcode
|
||||
OnSceneEvent?.Invoke(new SceneEvent()
|
||||
{
|
||||
SceneEventType = SceneEventType.Synchronize,
|
||||
ClientId = m_NetworkManager.LocalClientId,
|
||||
ClientId = NetworkManager.LocalClientId,
|
||||
});
|
||||
|
||||
OnSynchronize?.Invoke(m_NetworkManager.LocalClientId);
|
||||
OnSynchronize?.Invoke(NetworkManager.LocalClientId);
|
||||
}
|
||||
|
||||
// Always check to see if the scene needs to be validated
|
||||
if (!ValidateSceneBeforeLoading(sceneHash, loadSceneMode))
|
||||
{
|
||||
HandleClientSceneEvent(sceneEventId);
|
||||
if (m_NetworkManager.LogLevel == LogLevel.Developer)
|
||||
if (NetworkManager.LogLevel == LogLevel.Developer)
|
||||
{
|
||||
NetworkLog.LogInfo($"Client declined to load the scene {sceneName}, continuing with synchronization.");
|
||||
}
|
||||
@@ -1835,12 +1842,12 @@ namespace Unity.Netcode
|
||||
// it should pass through to post load processing (ClientLoadedSynchronization).
|
||||
// For ClientSynchronizationMode LoadSceneMode.Additive, if the scene is already loaded or the active scene is the scene to be loaded (does not require it to
|
||||
// be the initial primary scene) then go ahead and pass through to post load processing (ClientLoadedSynchronization).
|
||||
var shouldPassThrough = SceneManagerHandler.ClientShouldPassThrough(sceneName, sceneHash == sceneEventData.SceneHash, ClientSynchronizationMode, m_NetworkManager);
|
||||
var shouldPassThrough = SceneManagerHandler.ClientShouldPassThrough(sceneName, sceneHash == sceneEventData.SceneHash, ClientSynchronizationMode, NetworkManager);
|
||||
|
||||
if (!shouldPassThrough)
|
||||
{
|
||||
// If not, then load the scene
|
||||
var sceneEventProgress = new SceneEventProgress(m_NetworkManager)
|
||||
var sceneEventProgress = new SceneEventProgress(NetworkManager)
|
||||
{
|
||||
SceneEventId = sceneEventId,
|
||||
OnSceneEventCompleted = ClientLoadedSynchronization
|
||||
@@ -1854,10 +1861,10 @@ namespace Unity.Netcode
|
||||
SceneEventType = SceneEventType.Load,
|
||||
LoadSceneMode = loadSceneMode,
|
||||
SceneName = sceneName,
|
||||
ClientId = m_NetworkManager.LocalClientId,
|
||||
ClientId = NetworkManager.LocalClientId,
|
||||
});
|
||||
|
||||
OnLoad?.Invoke(m_NetworkManager.LocalClientId, sceneName, loadSceneMode, sceneLoad);
|
||||
OnLoad?.Invoke(NetworkManager.LocalClientId, sceneName, loadSceneMode, sceneLoad);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1875,7 +1882,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
var sceneEventData = SceneEventDataStore[sceneEventId];
|
||||
var sceneName = SceneNameFromHash(sceneEventData.ClientSceneHash);
|
||||
var nextScene = SceneManagerHandler.GetSceneFromLoadedScenes(sceneName, m_NetworkManager);
|
||||
var nextScene = SceneManagerHandler.GetSceneFromLoadedScenes(sceneName, NetworkManager);
|
||||
if (!nextScene.IsValid())
|
||||
{
|
||||
nextScene = GetAndAddNewlyLoadedSceneByName(sceneName);
|
||||
@@ -1915,9 +1922,9 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = responseSceneEventData
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ServerClientId);
|
||||
var size = NetworkManager.ConnectionManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ServerClientId);
|
||||
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(NetworkManager.ServerClientId, (uint)responseSceneEventData.SceneEventType, sceneName, size);
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventSent(NetworkManager.ServerClientId, (uint)responseSceneEventData.SceneEventType, sceneName, size);
|
||||
|
||||
EndSceneEvent(responseSceneEventData.SceneEventId);
|
||||
|
||||
@@ -1928,10 +1935,10 @@ namespace Unity.Netcode
|
||||
LoadSceneMode = loadSceneMode,
|
||||
SceneName = sceneName,
|
||||
Scene = nextScene,
|
||||
ClientId = m_NetworkManager.LocalClientId,
|
||||
ClientId = NetworkManager.LocalClientId,
|
||||
});
|
||||
|
||||
OnLoadComplete?.Invoke(m_NetworkManager.LocalClientId, sceneName, loadSceneMode);
|
||||
OnLoadComplete?.Invoke(NetworkManager.LocalClientId, sceneName, loadSceneMode);
|
||||
|
||||
// Check to see if we still have scenes to load and synchronize with
|
||||
HandleClientSceneEvent(sceneEventId);
|
||||
@@ -1944,7 +1951,7 @@ namespace Unity.Netcode
|
||||
/// </summary>
|
||||
private void SynchronizeNetworkObjectScene()
|
||||
{
|
||||
foreach (var networkObject in m_NetworkManager.SpawnManager.SpawnedObjectsList)
|
||||
foreach (var networkObject in NetworkManager.SpawnManager.SpawnedObjectsList)
|
||||
{
|
||||
// This is only done for dynamically spawned NetworkObjects
|
||||
// Theoretically, a server could have NetworkObjects in a server-side only scene, if the client doesn't have that scene loaded
|
||||
@@ -1969,9 +1976,9 @@ namespace Unity.Netcode
|
||||
|
||||
SceneManager.MoveGameObjectToScene(networkObject.gameObject, scene);
|
||||
}
|
||||
else if (m_NetworkManager.LogLevel <= LogLevel.Normal)
|
||||
else if (NetworkManager.LogLevel <= LogLevel.Normal)
|
||||
{
|
||||
NetworkLog.LogWarningServer($"[Client-{m_NetworkManager.LocalClientId}][{networkObject.gameObject.name}] Server - " +
|
||||
NetworkLog.LogWarningServer($"[Client-{NetworkManager.LocalClientId}][{networkObject.gameObject.name}] Server - " +
|
||||
$"client scene mismatch detected! Client-side has no scene loaded with handle ({networkObject.SceneOriginHandle})!");
|
||||
}
|
||||
}
|
||||
@@ -2026,8 +2033,6 @@ namespace Unity.Netcode
|
||||
{
|
||||
// Include anything in the DDOL scene
|
||||
PopulateScenePlacedObjects(DontDestroyOnLoadScene, false);
|
||||
// Synchronize the NetworkObjects for this scene
|
||||
sceneEventData.SynchronizeSceneNetworkObjects(m_NetworkManager);
|
||||
|
||||
// If needed, set the currently active scene
|
||||
if (HashToBuildIndex.ContainsKey(sceneEventData.ActiveSceneHash))
|
||||
@@ -2039,23 +2044,26 @@ namespace Unity.Netcode
|
||||
}
|
||||
}
|
||||
|
||||
// If needed, migrate dynamically spawned NetworkObjects to the same scene as on the server side
|
||||
// Spawn and Synchronize all NetworkObjects
|
||||
sceneEventData.SynchronizeSceneNetworkObjects(NetworkManager);
|
||||
|
||||
// If needed, migrate dynamically spawned NetworkObjects to the same scene as they are on the server
|
||||
SynchronizeNetworkObjectScene();
|
||||
|
||||
sceneEventData.SceneEventType = SceneEventType.SynchronizeComplete;
|
||||
SendSceneEventData(sceneEventId, new ulong[] { NetworkManager.ServerClientId });
|
||||
|
||||
// All scenes are synchronized, let the server know we are done synchronizing
|
||||
m_NetworkManager.IsConnectedClient = true;
|
||||
NetworkManager.IsConnectedClient = true;
|
||||
|
||||
// Client is now synchronized and fully "connected". This also means the client can send "RPCs" at this time
|
||||
m_NetworkManager.InvokeOnClientConnectedCallback(m_NetworkManager.LocalClientId);
|
||||
NetworkManager.ConnectionManager.InvokeOnClientConnectedCallback(NetworkManager.LocalClientId);
|
||||
|
||||
// Notify the client that they have finished synchronizing
|
||||
OnSceneEvent?.Invoke(new SceneEvent()
|
||||
{
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
ClientId = m_NetworkManager.LocalClientId, // Client sent this to the server
|
||||
ClientId = NetworkManager.LocalClientId, // Client sent this to the server
|
||||
});
|
||||
|
||||
// Process any SceneEventType.ObjectSceneChanged messages that
|
||||
@@ -2068,10 +2076,10 @@ namespace Unity.Netcode
|
||||
// scene not synchronized by the server will remain loaded)
|
||||
if (PostSynchronizationSceneUnloading && ClientSynchronizationMode == LoadSceneMode.Additive)
|
||||
{
|
||||
SceneManagerHandler.UnloadUnassignedScenes(m_NetworkManager);
|
||||
SceneManagerHandler.UnloadUnassignedScenes(NetworkManager);
|
||||
}
|
||||
|
||||
OnSynchronizeComplete?.Invoke(m_NetworkManager.LocalClientId);
|
||||
OnSynchronizeComplete?.Invoke(NetworkManager.LocalClientId);
|
||||
|
||||
EndSceneEvent(sceneEventId);
|
||||
}
|
||||
@@ -2191,11 +2199,11 @@ namespace Unity.Netcode
|
||||
// TODO 2023: We should have a better name for this or have multiple states the
|
||||
// client progresses through (the name and associated legacy behavior/expected state
|
||||
// of the client was persisted since MLAPI)
|
||||
m_NetworkManager.InvokeOnClientConnectedCallback(clientId);
|
||||
NetworkManager.ConnectionManager.InvokeOnClientConnectedCallback(clientId);
|
||||
|
||||
// Check to see if the client needs to resynchronize and before sending the message make sure the client is still connected to avoid
|
||||
// a potential crash within the MessageSystem (i.e. sending to a client that no longer exists)
|
||||
if (sceneEventData.ClientNeedsReSynchronization() && !DisableReSynchronization && m_NetworkManager.ConnectedClients.ContainsKey(clientId))
|
||||
if (sceneEventData.ClientNeedsReSynchronization() && !DisableReSynchronization && NetworkManager.ConnectedClients.ContainsKey(clientId))
|
||||
{
|
||||
sceneEventData.SceneEventType = SceneEventType.ReSynchronize;
|
||||
SendSceneEventData(sceneEventId, new ulong[] { clientId });
|
||||
@@ -2225,13 +2233,13 @@ namespace Unity.Netcode
|
||||
/// <param name="reader">data associated with the scene event</param>
|
||||
internal void HandleSceneEvent(ulong clientId, FastBufferReader reader)
|
||||
{
|
||||
if (m_NetworkManager != null)
|
||||
if (NetworkManager != null)
|
||||
{
|
||||
var sceneEventData = BeginSceneEvent();
|
||||
|
||||
sceneEventData.Deserialize(reader);
|
||||
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventReceived(
|
||||
NetworkManager.NetworkMetrics.TrackSceneEventReceived(
|
||||
clientId, (uint)sceneEventData.SceneEventType, SceneNameFromHash(sceneEventData.SceneHash), reader.Length);
|
||||
|
||||
if (sceneEventData.IsSceneEventClientSide())
|
||||
@@ -2250,7 +2258,7 @@ namespace Unity.Netcode
|
||||
// used if the server is synchronizing the same scenes (i.e. if a matching scene is already loaded on the
|
||||
// client side, then that scene will be used as opposed to loading another scene). This allows for clients
|
||||
// to reconnect to a network session without having to unload all of the scenes and reload all of the scenes.
|
||||
SceneManagerHandler.PopulateLoadedScenes(ref ScenesLoaded, m_NetworkManager);
|
||||
SceneManagerHandler.PopulateLoadedScenes(ref ScenesLoaded, NetworkManager);
|
||||
}
|
||||
}
|
||||
HandleClientSceneEvent(sceneEventData.SceneEventId);
|
||||
@@ -2262,7 +2270,7 @@ namespace Unity.Netcode
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"{nameof(HandleSceneEvent)} was invoked but {nameof(NetworkManager)} reference was null!");
|
||||
Debug.LogError($"{nameof(HandleSceneEvent)} was invoked but {nameof(Netcode.NetworkManager)} reference was null!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2274,7 +2282,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
// Create a local copy of the spawned objects list since the spawn manager will adjust the list as objects
|
||||
// are despawned.
|
||||
var localSpawnedObjectsHashSet = new HashSet<NetworkObject>(m_NetworkManager.SpawnManager.SpawnedObjectsList);
|
||||
var localSpawnedObjectsHashSet = new HashSet<NetworkObject>(NetworkManager.SpawnManager.SpawnedObjectsList);
|
||||
foreach (var networkObject in localSpawnedObjectsHashSet)
|
||||
{
|
||||
if (networkObject == null || (networkObject != null && networkObject.gameObject.scene == DontDestroyOnLoadScene))
|
||||
@@ -2291,7 +2299,7 @@ namespace Unity.Netcode
|
||||
UnityEngine.Object.DontDestroyOnLoad(networkObject.gameObject);
|
||||
}
|
||||
}
|
||||
else if (m_NetworkManager.IsServer)
|
||||
else if (NetworkManager.IsServer)
|
||||
{
|
||||
networkObject.Despawn();
|
||||
}
|
||||
@@ -2330,7 +2338,7 @@ namespace Unity.Netcode
|
||||
var globalObjectIdHash = networkObjectInstance.GlobalObjectIdHash;
|
||||
var sceneHandle = networkObjectInstance.gameObject.scene.handle;
|
||||
// We check to make sure the NetworkManager instance is the same one to be "NetcodeIntegrationTestHelpers" compatible and filter the list on a per scene basis (for additive scenes)
|
||||
if (networkObjectInstance.IsSceneObject != false && (networkObjectInstance.NetworkManager == m_NetworkManager ||
|
||||
if (networkObjectInstance.IsSceneObject != false && (networkObjectInstance.NetworkManager == NetworkManager ||
|
||||
networkObjectInstance.NetworkManagerOwner == null) && sceneHandle == sceneToFilterBy.handle)
|
||||
{
|
||||
if (!ScenePlacedObjects.ContainsKey(globalObjectIdHash))
|
||||
@@ -2358,7 +2366,7 @@ namespace Unity.Netcode
|
||||
/// <param name="scene">scene to move the NetworkObjects to</param>
|
||||
internal void MoveObjectsFromDontDestroyOnLoadToScene(Scene scene)
|
||||
{
|
||||
foreach (var networkObject in m_NetworkManager.SpawnManager.SpawnedObjectsList)
|
||||
foreach (var networkObject in NetworkManager.SpawnManager.SpawnedObjectsList)
|
||||
{
|
||||
if (networkObject == null)
|
||||
{
|
||||
@@ -2389,9 +2397,9 @@ namespace Unity.Netcode
|
||||
internal void NotifyNetworkObjectSceneChanged(NetworkObject networkObject)
|
||||
{
|
||||
// Really, this should never happen but in case it does
|
||||
if (!m_NetworkManager.IsServer)
|
||||
if (!NetworkManager.IsServer)
|
||||
{
|
||||
if (m_NetworkManager.LogLevel == LogLevel.Developer)
|
||||
if (NetworkManager.LogLevel == LogLevel.Developer)
|
||||
{
|
||||
NetworkLog.LogErrorServer("[Please Report This Error][NotifyNetworkObjectSceneChanged] A client is trying to notify of an object's scene change!");
|
||||
}
|
||||
@@ -2402,7 +2410,7 @@ namespace Unity.Netcode
|
||||
if (networkObject.IsSceneObject != false)
|
||||
{
|
||||
// Really, this should ever happen but in case it does
|
||||
if (m_NetworkManager.LogLevel == LogLevel.Developer)
|
||||
if (NetworkManager.LogLevel == LogLevel.Developer)
|
||||
{
|
||||
NetworkLog.LogErrorServer("[Please Report This Error][NotifyNetworkObjectSceneChanged] Trying to notify in-scene placed object scene change!");
|
||||
}
|
||||
@@ -2468,20 +2476,57 @@ namespace Unity.Netcode
|
||||
ObjectsMigratedIntoNewScene.Clear();
|
||||
}
|
||||
|
||||
|
||||
private List<int> m_ScenesToRemoveFromObjectMigration = new List<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Should be invoked during PostLateUpdate just prior to the
|
||||
/// MessagingSystem processes its outbound message queue.
|
||||
/// Should be invoked during PostLateUpdate just prior to the NetworkMessageManager processes its outbound message queue.
|
||||
/// </summary>
|
||||
internal void CheckForAndSendNetworkObjectSceneChanged()
|
||||
{
|
||||
// Early exit if not the server or there is nothing pending
|
||||
if (!m_NetworkManager.IsServer || ObjectsMigratedIntoNewScene.Count == 0)
|
||||
if (!NetworkManager.IsServer || ObjectsMigratedIntoNewScene.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Double check that the NetworkObjects to migrate still exist
|
||||
m_ScenesToRemoveFromObjectMigration.Clear();
|
||||
foreach (var sceneEntry in ObjectsMigratedIntoNewScene)
|
||||
{
|
||||
for (int i = sceneEntry.Value.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// Remove NetworkObjects that are no longer spawned
|
||||
if (!sceneEntry.Value[i].IsSpawned)
|
||||
{
|
||||
sceneEntry.Value.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
// If the scene entry no longer has any NetworkObjects to migrate
|
||||
// then add it to the list of scenes to be removed from the table
|
||||
// of scenes containing NetworkObjects to migrate.
|
||||
if (sceneEntry.Value.Count == 0)
|
||||
{
|
||||
m_ScenesToRemoveFromObjectMigration.Add(sceneEntry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove sceneHandle entries that no longer have any NetworkObjects remaining
|
||||
foreach (var sceneHandle in m_ScenesToRemoveFromObjectMigration)
|
||||
{
|
||||
ObjectsMigratedIntoNewScene.Remove(sceneHandle);
|
||||
}
|
||||
|
||||
// If there is nothing to send a migration notification for then exit
|
||||
if (ObjectsMigratedIntoNewScene.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Some NetworkObjects still exist, send the message
|
||||
var sceneEvent = BeginSceneEvent();
|
||||
sceneEvent.SceneEventType = SceneEventType.ObjectSceneChanged;
|
||||
SendSceneEventData(sceneEvent.SceneEventId, m_NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
SendSceneEventData(sceneEvent.SceneEventId, NetworkManager.ConnectedClientsIds.Where(c => c != NetworkManager.ServerClientId).ToArray());
|
||||
EndSceneEvent(sceneEvent.SceneEventId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user