com.unity.netcode.gameobjects@1.0.0-pre.7
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.0.0-pre.7] - 2022-04-01 ### Added - Added editor only check prior to entering into play mode if the currently open and active scene is in the build list and if not displays a dialog box asking the user if they would like to automatically add it prior to entering into play mode. (#1828) - Added `UnityTransport` implementation and `com.unity.transport` package dependency (#1823) - Added `NetworkVariableWritePermission` to `NetworkVariableBase` and implemented `Owner` client writable netvars. (#1762) - `UnityTransport` settings can now be set programmatically. (#1845) - `FastBufferWriter` and Reader IsInitialized property. (#1859) ### Changed - Updated `UnityTransport` dependency on `com.unity.transport` to 1.0.0 (#1849) ### Removed - Removed `SnapshotSystem` (#1852) - Removed `com.unity.modules.animation`, `com.unity.modules.physics` and `com.unity.modules.physics2d` dependencies from the package (#1812) - Removed `com.unity.collections` dependency from the package (#1849) ### Fixed - Fixed in-scene placed NetworkObjects not being found/ignored after a client disconnects and then reconnects. (#1850) - Fixed issue where `UnityTransport` send queues were not flushed when calling `DisconnectLocalClient` or `DisconnectRemoteClient`. (#1847) - Fixed NetworkBehaviour dependency verification check for an existing NetworkObject not searching from root parent transform relative GameObject. (#1841) - Fixed issue where entries were not being removed from the NetworkSpawnManager.OwnershipToObjectsTable. (#1838) - Fixed ClientRpcs would always send to all connected clients by default as opposed to only sending to the NetworkObject's Observers list by default. (#1836) - Fixed clarity for NetworkSceneManager client side notification when it receives a scene hash value that does not exist in its local hash table. (#1828) - Fixed client throws a key not found exception when it times out using UNet or UTP. (#1821) - Fixed network variable updates are no longer limited to 32,768 bytes when NetworkConfig.EnsureNetworkVariableLengthSafety is enabled. The limits are now determined by what the transport can send in a message. (#1811) - Fixed in-scene NetworkObjects get destroyed if a client fails to connect and shuts down the NetworkManager. (#1809) - Fixed user never being notified in the editor that a NetworkBehaviour requires a NetworkObject to function properly. (#1808) - Fixed PlayerObjects and dynamically spawned NetworkObjects not being added to the NetworkClient's OwnedObjects (#1801) - Fixed issue where NetworkManager would continue starting even if the NetworkTransport selected failed. (#1780) - Fixed issue when spawning new player if an already existing player exists it does not remove IsPlayer from the previous player (#1779) - Fixed lack of notification that NetworkManager and NetworkObject cannot be added to the same GameObject with in-editor notifications (#1777) - Fixed parenting warning printing for false positives (#1855)
This commit is contained in:
@@ -132,7 +132,7 @@ namespace Unity.Netcode
|
||||
private const NetworkDelivery k_DeliveryType = NetworkDelivery.ReliableFragmentedSequenced;
|
||||
internal const int InvalidSceneNameOrPath = -1;
|
||||
|
||||
// Used to be able to turn re-synchronization off for future snapshot development purposes.
|
||||
// Used to be able to turn re-synchronization off
|
||||
internal static bool DisableReSynchronization;
|
||||
|
||||
/// <summary>
|
||||
@@ -488,8 +488,18 @@ namespace Unity.Netcode
|
||||
var scenePath = SceneUtility.GetScenePathByBuildIndex(i);
|
||||
var hash = XXHash.Hash32(scenePath);
|
||||
var buildIndex = SceneUtility.GetBuildIndexByScenePath(scenePath);
|
||||
HashToBuildIndex.Add(hash, buildIndex);
|
||||
BuildIndexToHash.Add(buildIndex, hash);
|
||||
|
||||
// In the rare-case scenario where a programmatically generated build has duplicate
|
||||
// scene entries, we will log an error and skip the entry
|
||||
if (!HashToBuildIndex.ContainsKey(hash))
|
||||
{
|
||||
HashToBuildIndex.Add(hash, buildIndex);
|
||||
BuildIndexToHash.Add(buildIndex, hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"{nameof(NetworkSceneManager)} is skipping duplicate scene path entry {scenePath}. Make sure your scenes in build list does not contain duplicates!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +530,8 @@ namespace Unity.Netcode
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Scene Hash {sceneHash} does not exist in the {nameof(HashToBuildIndex)} table!");
|
||||
throw new Exception($"Scene Hash {sceneHash} does not exist in the {nameof(HashToBuildIndex)} table! Verify that all scenes requiring" +
|
||||
$" server to client synchronization are in the scenes in build list.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,7 +887,7 @@ namespace Unity.Netcode
|
||||
{
|
||||
SceneEventType = sceneEventProgress.SceneEventType,
|
||||
SceneName = SceneNameFromHash(sceneEventProgress.SceneHash),
|
||||
ClientId = m_NetworkManager.ServerClientId,
|
||||
ClientId = NetworkManager.ServerClientId,
|
||||
LoadSceneMode = sceneEventProgress.LoadSceneMode,
|
||||
ClientsThatCompleted = sceneEventProgress.DoneClients,
|
||||
ClientsThatTimedOut = m_NetworkManager.ConnectedClients.Keys.Except(sceneEventProgress.DoneClients).ToList(),
|
||||
@@ -947,10 +958,10 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = sceneName,
|
||||
ClientId = m_NetworkManager.ServerClientId // Server can only invoke this
|
||||
ClientId = NetworkManager.ServerClientId // Server can only invoke this
|
||||
});
|
||||
|
||||
OnUnload?.Invoke(m_NetworkManager.ServerClientId, sceneName, sceneUnload);
|
||||
OnUnload?.Invoke(NetworkManager.ServerClientId, sceneName, sceneUnload);
|
||||
|
||||
//Return the status
|
||||
return sceneEventProgress.Status;
|
||||
@@ -1017,12 +1028,12 @@ namespace Unity.Netcode
|
||||
// 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 != m_NetworkManager.ServerClientId).ToArray());
|
||||
SendSceneEventData(sceneEventId, m_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)
|
||||
{
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].AddClientAsDone(m_NetworkManager.ServerClientId);
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].AddClientAsDone(NetworkManager.ServerClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,7 +1046,7 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
|
||||
ClientId = m_NetworkManager.IsServer ? m_NetworkManager.ServerClientId : m_NetworkManager.LocalClientId
|
||||
ClientId = m_NetworkManager.IsServer ? NetworkManager.ServerClientId : m_NetworkManager.LocalClientId
|
||||
});
|
||||
|
||||
OnUnloadComplete?.Invoke(m_NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash));
|
||||
@@ -1043,7 +1054,7 @@ namespace Unity.Netcode
|
||||
// Clients send a notification back to the server they have completed the unload scene event
|
||||
if (!m_NetworkManager.IsServer)
|
||||
{
|
||||
SendSceneEventData(sceneEventId, new ulong[] { m_NetworkManager.ServerClientId });
|
||||
SendSceneEventData(sceneEventId, new ulong[] { NetworkManager.ServerClientId });
|
||||
}
|
||||
|
||||
EndSceneEvent(sceneEventId);
|
||||
@@ -1079,7 +1090,7 @@ namespace Unity.Netcode
|
||||
SceneEventType = SceneEventType.Unload,
|
||||
SceneName = keyHandleEntry.Value.name,
|
||||
LoadSceneMode = LoadSceneMode.Additive, // The only scenes unloaded are scenes that were additively loaded
|
||||
ClientId = m_NetworkManager.ServerClientId
|
||||
ClientId = NetworkManager.ServerClientId
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1147,10 +1158,10 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = sceneName,
|
||||
ClientId = m_NetworkManager.ServerClientId
|
||||
ClientId = NetworkManager.ServerClientId
|
||||
});
|
||||
|
||||
OnLoad?.Invoke(m_NetworkManager.ServerClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
|
||||
OnLoad?.Invoke(NetworkManager.ServerClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
|
||||
|
||||
//Return our scene progress instance
|
||||
return sceneEventProgress.Status;
|
||||
@@ -1187,7 +1198,6 @@ namespace Unity.Netcode
|
||||
// When it is set: Just before starting the asynchronous loading call
|
||||
// When it is unset: After the scene has loaded, the PopulateScenePlacedObjects is called, and all NetworkObjects in the do
|
||||
// not destroy temporary scene are moved into the active scene
|
||||
// TODO: When Snapshot scene spawning is enabled this needs to be removed.
|
||||
if (sceneEventData.LoadSceneMode == LoadSceneMode.Single)
|
||||
{
|
||||
IsSpawnedObjectsPendingInDontDestroyOnLoad = true;
|
||||
@@ -1278,7 +1288,9 @@ namespace Unity.Netcode
|
||||
{
|
||||
if (!keyValuePairBySceneHandle.Value.IsPlayerObject)
|
||||
{
|
||||
m_NetworkManager.SpawnManager.SpawnNetworkObjectLocally(keyValuePairBySceneHandle.Value, m_NetworkManager.SpawnManager.GetNetworkObjectId(), true, false, null, true);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1290,7 +1302,7 @@ namespace Unity.Netcode
|
||||
for (int j = 0; j < m_NetworkManager.ConnectedClientsList.Count; j++)
|
||||
{
|
||||
var clientId = m_NetworkManager.ConnectedClientsList[j].ClientId;
|
||||
if (clientId != m_NetworkManager.ServerClientId)
|
||||
if (clientId != NetworkManager.ServerClientId)
|
||||
{
|
||||
sceneEventData.TargetClientId = clientId;
|
||||
var message = new SceneEventMessage
|
||||
@@ -1309,16 +1321,16 @@ namespace Unity.Netcode
|
||||
SceneEventType = SceneEventType.LoadComplete,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
|
||||
ClientId = m_NetworkManager.ServerClientId,
|
||||
ClientId = NetworkManager.ServerClientId,
|
||||
Scene = scene,
|
||||
});
|
||||
|
||||
OnLoadComplete?.Invoke(m_NetworkManager.ServerClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
|
||||
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)
|
||||
{
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].AddClientAsDone(m_NetworkManager.ServerClientId);
|
||||
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].AddClientAsDone(NetworkManager.ServerClientId);
|
||||
}
|
||||
EndSceneEvent(sceneEventId);
|
||||
}
|
||||
@@ -1333,7 +1345,7 @@ namespace Unity.Netcode
|
||||
sceneEventData.DeserializeScenePlacedObjects();
|
||||
|
||||
sceneEventData.SceneEventType = SceneEventType.LoadComplete;
|
||||
SendSceneEventData(sceneEventId, new ulong[] { m_NetworkManager.ServerClientId });
|
||||
SendSceneEventData(sceneEventId, new ulong[] { NetworkManager.ServerClientId });
|
||||
m_IsSceneEventActive = false;
|
||||
|
||||
// Notify local client that the scene was loaded
|
||||
@@ -1544,9 +1556,9 @@ namespace Unity.Netcode
|
||||
{
|
||||
EventData = responseSceneEventData
|
||||
};
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, m_NetworkManager.ServerClientId);
|
||||
var size = m_NetworkManager.SendMessage(ref message, k_DeliveryType, NetworkManager.ServerClientId);
|
||||
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(m_NetworkManager.ServerClientId, (uint)responseSceneEventData.SceneEventType, sceneName, size);
|
||||
m_NetworkManager.NetworkMetrics.TrackSceneEventSent(NetworkManager.ServerClientId, (uint)responseSceneEventData.SceneEventType, sceneName, size);
|
||||
|
||||
EndSceneEvent(responseSceneEventData.SceneEventId);
|
||||
|
||||
@@ -1600,7 +1612,7 @@ namespace Unity.Netcode
|
||||
sceneEventData.SynchronizeSceneNetworkObjects(m_NetworkManager);
|
||||
|
||||
sceneEventData.SceneEventType = SceneEventType.SynchronizeComplete;
|
||||
SendSceneEventData(sceneEventId, new ulong[] { m_NetworkManager.ServerClientId });
|
||||
SendSceneEventData(sceneEventId, new ulong[] { NetworkManager.ServerClientId });
|
||||
|
||||
// All scenes are synchronized, let the server know we are done synchronizing
|
||||
m_NetworkManager.IsConnectedClient = true;
|
||||
@@ -1627,7 +1639,7 @@ namespace Unity.Netcode
|
||||
OnSceneEvent?.Invoke(new SceneEvent()
|
||||
{
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
ClientId = m_NetworkManager.ServerClientId, // Server sent this to client
|
||||
ClientId = NetworkManager.ServerClientId, // Server sent this to client
|
||||
});
|
||||
|
||||
EndSceneEvent(sceneEventId);
|
||||
@@ -1642,7 +1654,7 @@ namespace Unity.Netcode
|
||||
SceneEventType = sceneEventData.SceneEventType,
|
||||
LoadSceneMode = sceneEventData.LoadSceneMode,
|
||||
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
|
||||
ClientId = m_NetworkManager.ServerClientId,
|
||||
ClientId = NetworkManager.ServerClientId,
|
||||
ClientsThatCompleted = sceneEventData.ClientsCompleted,
|
||||
ClientsThatTimedOut = sceneEventData.ClientsTimedOut,
|
||||
});
|
||||
@@ -1734,8 +1746,6 @@ namespace Unity.Netcode
|
||||
// NetworkObjects
|
||||
m_NetworkManager.InvokeOnClientConnectedCallback(clientId);
|
||||
|
||||
// TODO: This check and associated code can be removed once we determine all
|
||||
// snapshot destroy messages are being updated until the server receives ACKs
|
||||
if (sceneEventData.ClientNeedsReSynchronization() && !DisableReSynchronization)
|
||||
{
|
||||
sceneEventData.SceneEventType = SceneEventType.ReSynchronize;
|
||||
@@ -1830,7 +1840,7 @@ namespace Unity.Netcode
|
||||
/// Using the local scene relative Scene.handle as a sub-key to the root dictionary allows us to
|
||||
/// distinguish between duplicate in-scene placed NetworkObjects
|
||||
/// </summary>
|
||||
private void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearScenePlacedObjects = true)
|
||||
internal void PopulateScenePlacedObjects(Scene sceneToFilterBy, bool clearScenePlacedObjects = true)
|
||||
{
|
||||
if (clearScenePlacedObjects)
|
||||
{
|
||||
@@ -1845,25 +1855,26 @@ namespace Unity.Netcode
|
||||
// at the end of scene loading we use this list to soft synchronize all in-scene placed NetworkObjects
|
||||
foreach (var networkObjectInstance in networkObjects)
|
||||
{
|
||||
// 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 (additive scenes)
|
||||
if (networkObjectInstance.IsSceneObject == null && networkObjectInstance.NetworkManager == m_NetworkManager && networkObjectInstance.gameObject.scene == sceneToFilterBy &&
|
||||
networkObjectInstance.gameObject.scene.handle == sceneToFilterBy.handle)
|
||||
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 && networkObjectInstance.gameObject.scene == sceneToFilterBy &&
|
||||
sceneHandle == sceneToFilterBy.handle)
|
||||
{
|
||||
if (!ScenePlacedObjects.ContainsKey(networkObjectInstance.GlobalObjectIdHash))
|
||||
if (!ScenePlacedObjects.ContainsKey(globalObjectIdHash))
|
||||
{
|
||||
ScenePlacedObjects.Add(networkObjectInstance.GlobalObjectIdHash, new Dictionary<int, NetworkObject>());
|
||||
ScenePlacedObjects.Add(globalObjectIdHash, new Dictionary<int, NetworkObject>());
|
||||
}
|
||||
|
||||
if (!ScenePlacedObjects[networkObjectInstance.GlobalObjectIdHash].ContainsKey(networkObjectInstance.gameObject.scene.handle))
|
||||
if (!ScenePlacedObjects[globalObjectIdHash].ContainsKey(sceneHandle))
|
||||
{
|
||||
ScenePlacedObjects[networkObjectInstance.GlobalObjectIdHash].Add(networkObjectInstance.gameObject.scene.handle, networkObjectInstance);
|
||||
ScenePlacedObjects[globalObjectIdHash].Add(sceneHandle, networkObjectInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
var exitingEntryName = ScenePlacedObjects[networkObjectInstance.GlobalObjectIdHash][networkObjectInstance.gameObject.scene.handle] != null ?
|
||||
ScenePlacedObjects[networkObjectInstance.GlobalObjectIdHash][networkObjectInstance.gameObject.scene.handle].name : "Null Entry";
|
||||
var exitingEntryName = ScenePlacedObjects[globalObjectIdHash][sceneHandle] != null ? ScenePlacedObjects[globalObjectIdHash][sceneHandle].name : "Null Entry";
|
||||
throw new Exception($"{networkObjectInstance.name} tried to registered with {nameof(ScenePlacedObjects)} which already contains " +
|
||||
$"the same {nameof(NetworkObject.GlobalObjectIdHash)} value {networkObjectInstance.GlobalObjectIdHash} for {exitingEntryName}!");
|
||||
$"the same {nameof(NetworkObject.GlobalObjectIdHash)} value {globalObjectIdHash} for {exitingEntryName}!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace Unity.Netcode
|
||||
/// <b>Invocation:</b> Server Side<br/>
|
||||
/// <b>Message Flow:</b> Server to client<br/>
|
||||
/// <b>Event Notification:</b> Both server and client receive a local notification<br/>
|
||||
/// <em>Note: This will be removed once snapshot and buffered messages are finalized as it will no longer be needed at that point.</em>
|
||||
/// </summary>
|
||||
ReSynchronize,
|
||||
/// <summary>
|
||||
@@ -592,9 +591,6 @@ namespace Unity.Netcode
|
||||
networkObject.IsSpawned = false;
|
||||
if (m_NetworkManager.PrefabHandler.ContainsHandler(networkObject))
|
||||
{
|
||||
// Since this is the client side and we have missed the delete message, until the Snapshot system is in place for spawn and despawn handling
|
||||
// we have to remove this from the list of spawned objects manually or when a NetworkObjectId is recycled the client will throw an error
|
||||
// about the id already being assigned.
|
||||
if (m_NetworkManager.SpawnManager.SpawnedObjects.ContainsKey(networkObjectId))
|
||||
{
|
||||
m_NetworkManager.SpawnManager.SpawnedObjects.Remove(networkObjectId);
|
||||
|
||||
Reference in New Issue
Block a user