|
1 | 1 | #if UNIFIED_NETCODE |
| 2 | +using System; |
2 | 3 | using System.Collections.Generic; |
3 | 4 | using System.Diagnostics.CodeAnalysis; |
4 | 5 | using Unity.Collections; |
5 | 6 | using Unity.Netcode.Logging; |
6 | 7 | using UnityEngine; |
| 8 | +using Object = UnityEngine.Object; |
7 | 9 |
|
8 | 10 | namespace Unity.Netcode |
9 | 11 | { |
| 12 | + /// <summary> |
| 13 | + /// Handles the management of ghost spawns during the synchronization process. This includes tracking pending NetworkObject spawns |
| 14 | + /// that are waiting for their associated ghost to be spawned before they can be fully deserialized. |
| 15 | + /// </summary> |
10 | 16 | internal class GhostSpawnManager |
11 | 17 | { |
12 | 18 | private readonly NetworkManager m_NetworkManager; |
@@ -139,16 +145,19 @@ internal NetworkObject ProcessGhostPendingSynchronization(ulong networkObjectId, |
139 | 145 | m_NetworkManager.SceneManager.SetTheSceneBeingSynchronized(serializedObject.NetworkSceneHandle); |
140 | 146 | } |
141 | 147 | var networkObject = NetworkObject.Deserialize(serializedObject, reader, m_NetworkManager); |
| 148 | + |
142 | 149 | // TODO-UNIFIED: How do we handle the "all in-scene placed objects are spawned notification"? |
143 | 150 | //if (serializedObject.IsSceneObject) |
144 | 151 | //{ |
145 | 152 | // networkObject.InternalInSceneNetworkObjectsSpawned(); |
146 | 153 | //} |
| 154 | + |
| 155 | + // If removing, determine if we have any pending ghosts remaining and dispose of this ghost's pending synchronization buffer. |
| 156 | + // If not removing, then we will keep the buffer around until we do remove it (either via spawn or timeout). |
147 | 157 | if (removeUponSpawn) |
148 | 158 | { |
149 | | - m_GhostsPendingSynchronization.Remove(networkObjectId); |
150 | 159 | m_GhostsArePendingSynchronization = m_GhostsPendingSynchronization.Count > 0; |
151 | | - ghostPendingSync.Buffer.Dispose(); |
| 160 | + ghostPendingSync.Dispose(); |
152 | 161 | } |
153 | 162 | return networkObject; |
154 | 163 | } |
@@ -255,5 +264,24 @@ internal void Shutdown() |
255 | 264 | m_GhostsPendingSynchronization.Clear(); |
256 | 265 | } |
257 | 266 | } |
| 267 | + |
| 268 | + /// <summary> |
| 269 | + /// Used to store pending ghost spawns that are waiting for their associated (N4E) ghost to be spawned before they can be fully deserialized and |
| 270 | + /// spawned during the scene synchronization process. This is necessary because in unified mode we allow for NetworkObjects with ghost components |
| 271 | + /// to be synchronized during the scene synchronization process but we can't guarantee the order of messages that the client receives so we |
| 272 | + /// need to defer the deserialization of any NetworkObject that has a ghost component until we have received the message that the ghost has |
| 273 | + /// been spawned and we have an instance to deserialize this information into. |
| 274 | + /// </summary> |
| 275 | + internal struct PendingGhostSpawnEntry : IDisposable |
| 276 | + { |
| 277 | + public float RegistrationTime; |
| 278 | + public FastBufferReader Buffer; |
| 279 | + public NetworkObject.SerializedObject SerializedObject; |
| 280 | + |
| 281 | + public void Dispose() |
| 282 | + { |
| 283 | + Buffer.Dispose(); |
| 284 | + } |
| 285 | + } |
258 | 286 | } |
259 | 287 | #endif |
0 commit comments