Skip to content

Commit 6757e63

Browse files
committed
Solved late-join problems
1 parent 3522fc0 commit 6757e63

2 files changed

Lines changed: 48 additions & 64 deletions

File tree

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ public uint PrefabIdHash
5757
}
5858
}
5959

60+
/// <summary>
61+
/// InstantiationData sent during the instantiation process.
62+
/// Retrieved in <see cref="INetworkPrefabInstanceHandlerWithData.OnSynchronizeInstantiationData{T}(ref BufferSerializer{T})"/>
63+
/// and available to INetworkPrefabInstanceHandler.Instantiate() for custom handling by user code.
64+
/// </summary>
65+
internal byte[] InstantiationData;
66+
6067
/// <summary>
6168
/// All <see cref="NetworkTransform"/> component instances associated with a <see cref="NetworkObject"/> component instance.
6269
/// </summary>
@@ -1814,6 +1821,8 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
18141821
}
18151822
}
18161823

1824+
InjectInstantiationData();
1825+
18171826
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManager.SpawnManager.GetNetworkObjectId(), IsSceneObject.HasValue && IsSceneObject.Value, playerObject, ownerClientId, destroyWithScene);
18181827

18191828
if ((NetworkManager.DistributedAuthorityMode && NetworkManager.DAHost) || (!NetworkManager.DistributedAuthorityMode && NetworkManager.IsServer))
@@ -1845,6 +1854,20 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
18451854
}
18461855
}
18471856

1857+
/// <summary>
1858+
/// Injects the instantiation data into the <see cref="InstantiationData"/> if available. This is used to synchronize
1859+
/// </summary>
1860+
internal void InjectInstantiationData()
1861+
{
1862+
if (NetworkManager.PrefabHandler.TryGetHandlerWithData(this.GlobalObjectIdHash, out var prefabHandler))
1863+
{
1864+
// Creates the instantiateData array for the newtwork object
1865+
var serializer = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(new FastBufferWriter(4, Collections.Allocator.Temp, int.MaxValue)));
1866+
prefabHandler.OnSynchronizeInstantiationData(ref serializer);
1867+
InstantiationData = serializer.GetFastBufferWriter().ToArray();
1868+
}
1869+
}
1870+
18481871
/// <summary>
18491872
/// This invokes <see cref="NetworkSpawnManager.InstantiateAndSpawn(NetworkObject, ulong, bool, bool, bool, Vector3, Quaternion)"/>.
18501873
/// </summary>
@@ -2984,7 +3007,8 @@ public void Serialize(FastBufferWriter writer)
29843007

29853008
if (HasInstantiationData)
29863009
{
2987-
OwnerObject.NetworkManager.PrefabHandler.SynchronizeInstantiationData(Hash, ref bufferSerializer);
3010+
writer.WriteValueSafe(OwnerObject.InstantiationData.Length);
3011+
writer.WriteBytesSafe(OwnerObject.InstantiationData);
29883012
}
29893013

29903014
OwnerObject.SynchronizeNetworkBehaviours(ref bufferSerializer, TargetClientId);
@@ -3164,9 +3188,8 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId = NetworkManager
31643188
Hash = CheckForGlobalObjectIdHashOverride(),
31653189
OwnerObject = this,
31663190
TargetClientId = targetClientId,
3167-
HasInstantiationData = NetworkManager.PrefabHandler.ContainsHandlerWithData(GlobalObjectIdHash),
3191+
HasInstantiationData = InstantiationData != null && InstantiationData.Length > 0
31683192
};
3169-
31703193
// Handle Parenting
31713194
if (!AlwaysReplicateAsRoot && obj.HasParent)
31723195
{
@@ -3234,7 +3257,7 @@ internal static NetworkObject AddSceneObject(in SceneObject sceneObject, FastBuf
32343257
//Synchronize the instantiation data if needed
32353258
if (sceneObject.HasInstantiationData)
32363259
{
3237-
networkManager.PrefabHandler.SynchronizeInstantiationData(sceneObject.Hash, ref bufferSerializer);
3260+
networkManager.PrefabHandler.ReadInstantiationData(sceneObject.Hash, ref bufferSerializer);
32383261
}
32393262

32403263
//Attempt to create a local NetworkObject

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs

Lines changed: 21 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,6 @@ public bool RemoveHandler(uint globalObjectIdHash)
226226
/// <returns>true or false</returns>
227227
internal bool ContainsHandler(uint networkPrefabHash) => m_PrefabAssetToPrefabHandler.ContainsKey(networkPrefabHash) || m_PrefabInstanceToPrefabAsset.ContainsKey(networkPrefabHash);
228228

229-
/// <summary>
230-
/// Check to see if a <see cref="NetworkObject.GlobalObjectIdHash"/> is registered to an <see cref="INetworkPrefabInstanceHandlerWithData"/> implementation
231-
/// </summary>
232-
/// <param name="objectHash"></param>
233-
/// <returns></returns>
234-
internal bool ContainsHandlerWithData(uint objectHash) => TryGetHandlerWithData(objectHash, out _);
235-
236229
/// <summary>
237230
/// Returns the <see cref="INetworkPrefabInstanceHandlerWithData"/> implementation for a given <see cref="NetworkObject.GlobalObjectIdHash"/>
238231
/// </summary>
@@ -259,68 +252,36 @@ internal bool TryGetHandlerWithData(uint objectHash, out INetworkPrefabInstanceH
259252
/// <typeparam name="T"></typeparam>
260253
/// <param name="objectHash"></param>
261254
/// <param name="serializer"></param>
262-
internal void SynchronizeInstantiationData<T>(uint objectHash, ref BufferSerializer<T> serializer) where T : IReaderWriter
255+
internal void ReadInstantiationData<T>(uint objectHash, ref BufferSerializer<T> serializer) where T : IReaderWriter
263256
{
264-
if (!TryGetHandlerWithData(objectHash, out INetworkPrefabInstanceHandlerWithData synchronizableHandler))
257+
if (!serializer.IsReader || !TryGetHandlerWithData(objectHash, out INetworkPrefabInstanceHandlerWithData synchronizableHandler))
265258
{
266259
return;
267260
}
268261

269-
if (serializer.IsWriter)
270-
{
271-
// Reserves space to write the instantiation data size later
272-
FastBufferWriter fastBufferWriter = serializer.GetFastBufferWriter();
273-
int dataSizePos = fastBufferWriter.Position;
274-
fastBufferWriter.WriteValueSafe(0); // placeholder for size, correctly writen at the end
275-
276-
int dataStartPos = fastBufferWriter.Position;
277-
try
278-
{
279-
synchronizableHandler.OnSynchronizeInstantiationData(ref serializer);
280-
}
281-
catch (Exception ex)
282-
{
283-
// Resets to start position to avoid writing corrupted data
284-
fastBufferWriter.Seek(dataSizePos);
285-
NetworkLog.LogError($"[InstantiationData] Handler failed during synchronization (Write): {ex.Message}");
286-
return;
287-
}
262+
FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
263+
// Reads the expected size of the instantiation data
264+
fastBufferReader.ReadValueSafe(out int dataSize);
265+
int dataStartPos = fastBufferReader.Position;
288266

289-
// Compute and write actual instantiation data size
290-
int dataEndPos = fastBufferWriter.Position;
291-
int dataSize = dataEndPos - dataStartPos;
292-
// Goes back and write the real size
293-
fastBufferWriter.Seek(dataSizePos);
294-
fastBufferWriter.WriteValueSafe(dataSize);
295-
// Restores to end
296-
fastBufferWriter.Seek(dataEndPos);
267+
try
268+
{
269+
synchronizableHandler.OnSynchronizeInstantiationData(ref serializer);
297270
}
298-
else
271+
catch (Exception ex)
299272
{
300-
FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
301-
// Reads the expected size of the instantiation data
302-
fastBufferReader.ReadValueSafe(out int dataSize);
303-
int dataStartPos = fastBufferReader.Position;
304-
305-
try
306-
{
307-
synchronizableHandler.OnSynchronizeInstantiationData(ref serializer);
308-
}
309-
catch (Exception ex)
310-
{
311-
// Skips the unread instantiation data bytes
312-
fastBufferReader.Seek(dataStartPos + dataSize);
313-
NetworkLog.LogError($"[InstantiationData] Handler failed during synchronization (Read): {ex.Message}");
314-
return;
315-
}
273+
// Skips the unread instantiation data bytes
274+
fastBufferReader.Seek(dataStartPos + dataSize);
275+
NetworkLog.LogError($"[InstantiationData] Handler failed during synchronization (Read): {ex.Message}");
276+
return;
277+
}
316278

317-
// Validates if expected number of bytes were read
318-
int dataEndPos = fastBufferReader.Position;
319-
if (dataEndPos != dataStartPos + dataSize)
320-
{
321-
NetworkLog.LogWarning($"[InstantiationData] Read {dataEndPos - dataStartPos} bytes, expected {dataSize}");
322-
fastBufferReader.Seek(dataStartPos + dataSize);
323-
}
279+
// Validates if expected number of bytes were read
280+
int dataEndPos = fastBufferReader.Position;
281+
if (dataEndPos != dataStartPos + dataSize)
282+
{
283+
NetworkLog.LogWarning($"[InstantiationData] Read {dataEndPos - dataStartPos} bytes, expected {dataSize}");
284+
fastBufferReader.Seek(dataStartPos + dataSize);
324285
}
325286
}
326287

0 commit comments

Comments
 (0)