Skip to content

Commit 3fd2bf5

Browse files
fix: Cannot Create Multiple Network Prefab Overrides That Target Same Network Prefab as Override [MTT-7399] (#2710)
* fix WIP fix for prefab overrides * update Removing restriction on PrefabIdHash. No longer using OverrideToNetworkPrefab. * update Removing remains of OverrideToNetworkPrefab * fix: validation Putting back the NetworkPrefabs.OverrideToNetworkPrefab to avoid validation issues. * Update NetworkObject.cs Removing commented out code. * update Adding a new method: NetworkSpawnManager.InstantiateAndSpawn that handles several steps for users. Basically passing in a prefab NetworkObject will instantiate, spawn, and then return the spawned prefab instance. This takes into account prefab overrides. Added a manual test "SimpleSpawn" to manually validate the updates. * style spelling in xml API minor rewording * style expanded upon the GetNetworkObjectToSpawn description * style fixing namespace ordinal ordering * update Added some additional improvements to the simple spawn sample/manual test that also provides an example of the legacy/alternate way to spawn prefabs along with unique prefabs that are named appropriately for each scenario while also setting the color of the NetworkObjectId label to the assigned owner/client assigned color. * test and update This update includes automatic linking of in-scene placed NetworkObjects to their source prefab asset. This is specifically useful for when scene management is disabled as it removes the requirement to create a prefab override per in-scene placed NetworkObject. This also assures that a prefab with an override can still be used as an in-scene placed NetworkObject without the client spawning the overide when scene management is disabled while also still spawing the override of the same prefab when dynamically spawned. This also includes an integration test to validate both with and without scene management enabled that clients synchronize to the proper prefab instance. * test update and fix Reverting the NetworkPrefabs change and just using the SourcePrefabToOverride. Renamed InScenePlacedSourceGlobalObjectId to InScenePlacedSourceGlobalObjectIdHash to avoid confusion. Updated the PrefabExtendedTests and test assets to include the scenario that is not handled when scnee management is disabled (i.e. in-scene defined NetworkObjects). * style null check standard adjustment * update Adding logic to only spawn override (as a default) when running as a host. * update Repopulating the override dictionary to avoid breaking any user's project that utilizes it. Added NetworkObject.InstantiateAndSpawn method. * update Adding change log entries. * update Updating how errors and warning messages are handled. * test Validating that all error messages occur when expected. * style removing CR and adding an s to the end of TestsInstantiateAndSpawnErrors * fix Putting the OverrideToNetworkPrefab check in the right location. * update Adding back the OverrideToNetworkPrefab to continue to support the legacy manual instantiate and spawn usage pattern. Updated comments to reflect this and to point users to use InstantiateAndSpawn methods. * update Adding a static version of InstantiateAndSpawn to NetworkObject. * Test Adding a test pass for validating that the legacy instantiate and spawn usage pattern still works. --------- Co-authored-by: Unity Netcode CI <[email protected]>
1 parent 94a2ffc commit 3fd2bf5

File tree

58 files changed

+7371
-132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+7371
-132
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1818
- Added `NetworkManager.ServerIsHost` and `NetworkBehaviour.ServerIsHost` to allow a client to tell if it is connected to a host or to a dedicated server (#2762)
1919
- Added `SceneEventProgress.SceneManagementNotEnabled` return status to be returned when a `NetworkSceneManager` method is invoked and scene management is not enabled. (#2735)
2020
- Added `SceneEventProgress.ServerOnlyAction` return status to be returned when a `NetworkSceneManager` method is invoked by a client. (#2735)
21+
- Added `NetworkObject.InstantiateAndSpawn` and `NetworkSpawnManager.InstantiateAndSpawn` methods to simplify prefab spawning by assuring that the prefab is valid and applies any override prior to instantiating the `GameObject` and spawning the `NetworkObject` instance. (#2710)
2122

2223
### Fixed
2324

@@ -33,6 +34,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
3334
- Fixed issue where a parented in-scene placed NetworkObject would be destroyed upon a client or server exiting a network session but not unloading the original scene in which the NetworkObject was placed. (#2737)
3435
- Fixed issue where during client synchronization and scene loading, when client synchronization or the scene loading mode are set to `LoadSceneMode.Single`, a `CreateObjectMessage` could be received, processed, and the resultant spawned `NetworkObject` could be instantiated in the client's currently active scene that could, towards the end of the client synchronization or loading process, be unloaded and cause the newly created `NetworkObject` to be destroyed (and throw and exception). (#2735)
3536
- Fixed issue where a `NetworkTransform` instance with interpolation enabled would result in wide visual motion gaps (stuttering) under above normal latency conditions and a 1-5% or higher packet are drop rate. (#2713)
37+
- Fixed issue where you could not have multiple source network prefab overrides targeting the same network prefab as their override. (#2710)
3638

3739
### Changed
3840
- Changed the server or host shutdown so it will now perform a "soft shutdown" when `NetworkManager.Shutdown` is invoked. This will send a disconnect notification to all connected clients and the server-host will wait for all connected clients to disconnect or timeout after a 5 second period before completing the shutdown process. (#2789)
@@ -41,6 +43,11 @@ Additional documentation and release notes are available at [Multiplayer Documen
4143
- `NetworkManager.ConnectedClientsIds` is now accessible on the client side and will contain the list of all clients in the session, including the host client if the server is operating in host mode (#2762)
4244
- Changed `NetworkSceneManager` to return a `SceneEventProgress` status and not throw exceptions for methods invoked when scene management is disabled and when a client attempts to access a `NetworkSceneManager` method by a client. (#2735)
4345
- Changed `NetworkTransform` authoritative instance tick registration so a single `NetworkTransform` specific tick event update will update all authoritative instances to improve perofmance. (#2713)
46+
- Changed `NetworkPrefabs.OverrideToNetworkPrefab` dictionary is no longer used/populated due to it ending up being related to a regression bug and not allowing more than one override to be assigned to a network prefab asset. (#2710)
47+
- Changed in-scene placed `NetworkObject`s now store their source network prefab asset's `GlobalObjectIdHash` internally that is used, when scene management is disabled, by clients to spawn the correct prefab even if the `NetworkPrefab` entry has an override. This does not impact dynamically spawning the same prefab which will yield the override on both host and client. (#2710)
48+
- Changed in-scene placed `NetworkObject`s no longer require a `NetworkPrefab` entry with `GlobalObjectIdHash` override in order for clients to properly synchronize. (#2710)
49+
- Changed in-scene placed `NetworkObject`s now set their `IsSceneObject` value when generating their `GlobalObjectIdHash` value. (#2710)
50+
- Changed the default `NetworkConfig.SpawnTimeout` value from 1.0s to 10.0s. (#2710)
4451

4552
## [1.7.1] - 2023-11-15
4653

com.unity.netcode.gameobjects/Runtime/Configuration/NetworkConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public class NetworkConfig
132132
/// The amount of time a message should be buffered if the asset or object needed to process it doesn't exist yet. If the asset is not added/object is not spawned within this time, it will be dropped.
133133
/// </summary>
134134
[Tooltip("The amount of time a message should be buffered if the asset or object needed to process it doesn't exist yet. If the asset is not added/object is not spawned within this time, it will be dropped")]
135-
public float SpawnTimeout = 1f;
135+
public float SpawnTimeout = 10f;
136136

137137
/// <summary>
138138
/// Whether or not to enable network logs.

com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public class NetworkPrefabs
3030
[NonSerialized]
3131
public Dictionary<uint, NetworkPrefab> NetworkPrefabOverrideLinks = new Dictionary<uint, NetworkPrefab>();
3232

33+
/// <summary>
34+
/// This is used for the legacy way of spawning NetworkPrefabs with an override when manually instantiating and spawning.
35+
/// To handle multiple source NetworkPrefab overrides that all point to the same target NetworkPrefab use
36+
/// <see cref="NetworkSpawnManager.InstantiateAndSpawn(NetworkObject, ulong, bool, bool, bool, Vector3, Quaternion)"/>
37+
/// or <see cref="NetworkObject.InstantiateAndSpawn(NetworkManager, ulong, bool, bool, bool, Vector3, Quaternion)"/>
38+
/// </summary>
3339
[NonSerialized]
3440
public Dictionary<uint, uint> OverrideToNetworkPrefab = new Dictionary<uint, uint>();
3541

@@ -234,7 +240,8 @@ public bool Contains(GameObject prefab)
234240
{
235241
for (int i = 0; i < m_Prefabs.Count; i++)
236242
{
237-
if (m_Prefabs[i].Prefab == prefab)
243+
// Check both values as Prefab and be different than SourcePrefabToOverride
244+
if (m_Prefabs[i].Prefab == prefab || m_Prefabs[i].SourcePrefabToOverride == prefab)
238245
{
239246
return true;
240247
}
@@ -262,7 +269,7 @@ public bool Contains(NetworkPrefab prefab)
262269
}
263270

264271
/// <summary>
265-
/// Configures <see cref="NetworkPrefabOverrideLinks"/> and <see cref="OverrideToNetworkPrefab"/> for the given <see cref="NetworkPrefab"/>
272+
/// Configures <see cref="NetworkPrefabOverrideLinks"/> for the given <see cref="NetworkPrefab"/>
266273
/// </summary>
267274
private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
268275
{
@@ -296,28 +303,16 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab)
296303
return true;
297304
}
298305

299-
// Make sure we don't have several overrides targeting the same prefab. Apparently we don't support that... shame.
300-
if (OverrideToNetworkPrefab.ContainsKey(target))
301-
{
302-
var networkObject = networkPrefab.Prefab.GetComponent<NetworkObject>();
303-
304-
// This can happen if a user tries to make several GlobalObjectIdHash values point to the same target
305-
Debug.LogError($"{nameof(NetworkPrefab)} (\"{networkObject.name}\") has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} target entry value of: {target}!");
306-
return false;
307-
}
308-
309306
switch (networkPrefab.Override)
310307
{
311308
case NetworkPrefabOverride.Prefab:
312-
{
313-
NetworkPrefabOverrideLinks.Add(source, networkPrefab);
314-
OverrideToNetworkPrefab.Add(target, source);
315-
}
316-
break;
317309
case NetworkPrefabOverride.Hash:
318310
{
319311
NetworkPrefabOverrideLinks.Add(source, networkPrefab);
320-
OverrideToNetworkPrefab.Add(target, source);
312+
if (!OverrideToNetworkPrefab.ContainsKey(target))
313+
{
314+
OverrideToNetworkPrefab.Add(target, source);
315+
}
321316
}
322317
break;
323318
}

0 commit comments

Comments
 (0)