Skip to content

Commit 1d746fe

Browse files
committed
Merge branch 'feat/InstantiationPayload' into develop-2.0.0
2 parents b8765a2 + 6419ad0 commit 1d746fe

6 files changed

Lines changed: 53 additions & 99 deletions

File tree

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -797,9 +797,8 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
797797
// Server-side spawning (only if there is a prefab hash or player prefab provided)
798798
if (!NetworkManager.DistributedAuthorityMode && response.CreatePlayerObject && (response.PlayerPrefabHash.HasValue || NetworkManager.NetworkConfig.PlayerPrefab != null))
799799
{
800-
var instantiationPayloadWriter = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(new FastBufferWriter(16,Allocator.Temp, int.MaxValue)));
801-
var playerObject = response.PlayerPrefabHash.HasValue ? NetworkManager.SpawnManager.GetNetworkObjectToSpawn(response.PlayerPrefabHash.Value, ownerClientId, ref instantiationPayloadWriter, response.Position ?? null, response.Rotation ?? null)
802-
: NetworkManager.SpawnManager.GetNetworkObjectToSpawn(NetworkManager.NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash, ownerClientId, ref instantiationPayloadWriter, response.Position ?? null, response.Rotation ?? null);
800+
var playerObject = response.PlayerPrefabHash.HasValue ? NetworkManager.SpawnManager.GetNetworkObjectToSpawn(response.PlayerPrefabHash.Value, ownerClientId, response.Position ?? null, response.Rotation ?? null)
801+
: NetworkManager.SpawnManager.GetNetworkObjectToSpawn(NetworkManager.NetworkConfig.PlayerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash, ownerClientId, response.Position ?? null, response.Rotation ?? null);
803802

804803
// Spawn the player NetworkObject locally
805804
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(
@@ -951,8 +950,7 @@ internal void CreateAndSpawnPlayer(ulong ownerId)
951950
if (playerPrefab != null)
952951
{
953952
var globalObjectIdHash = playerPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
954-
var instantiationPayloadWriter = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(new FastBufferWriter(16, Allocator.Temp, int.MaxValue)));
955-
var networkObject = NetworkManager.SpawnManager.GetNetworkObjectToSpawn(globalObjectIdHash, ownerId, ref instantiationPayloadWriter, playerPrefab.transform.position, playerPrefab.transform.rotation);
953+
var networkObject = NetworkManager.SpawnManager.GetNetworkObjectToSpawn(globalObjectIdHash, ownerId, playerPrefab.transform.position, playerPrefab.transform.rotation);
956954
networkObject.IsSceneObject = false;
957955
networkObject.SpawnAsPlayerObject(ownerId, networkObject.DestroyWithScene);
958956
}

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

Lines changed: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Runtime.CompilerServices;
5-
using Unity.Collections;
65
using Unity.Netcode.Components;
76
#if UNITY_EDITOR
87
using UnityEditor;
@@ -46,13 +45,6 @@ public sealed class NetworkObject : MonoBehaviour
4645
[SerializeField]
4746
internal uint InScenePlacedSourceGlobalObjectIdHash;
4847

49-
/// <summary>
50-
/// Metadata sent during the instantiation process.
51-
/// Retrieved in INetworkCustomSpawnDataSynchronizer before instantiation,
52-
/// and available to INetworkPrefabInstanceHandler.Instantiate() for custom handling by user code.
53-
/// </summary>
54-
internal FastBufferReader InstantiationPayload;
55-
5648
/// <summary>
5749
/// Gets the Prefab Hash Id of this object if the object is registerd as a prefab otherwise it returns 0
5850
/// </summary>
@@ -1819,8 +1811,6 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla
18191811
}
18201812
}
18211813

1822-
NetworkManager.PrefabHandler.InjectInstantiationPayload(this);
1823-
18241814
NetworkManager.SpawnManager.SpawnNetworkObjectLocally(this, NetworkManager.SpawnManager.GetNetworkObjectId(), IsSceneObject.HasValue && IsSceneObject.Value, playerObject, ownerClientId, destroyWithScene);
18251815

18261816
if ((NetworkManager.DistributedAuthorityMode && NetworkManager.DAHost) || (!NetworkManager.DistributedAuthorityMode && NetworkManager.IsServer))
@@ -2822,7 +2812,6 @@ internal struct SceneObject
28222812
public ulong NetworkObjectId;
28232813
public ulong OwnerClientId;
28242814
public ushort OwnershipFlags;
2825-
public FastBufferReader InstantiationPayload;
28262815

28272816
public bool IsPlayerObject
28282817
{
@@ -2965,26 +2954,12 @@ public void Serialize(FastBufferWriter writer)
29652954
var writeSize = 0;
29662955
writeSize += HasTransform ? FastBufferWriter.GetWriteSize<TransformData>() : 0;
29672956
writeSize += FastBufferWriter.GetWriteSize<int>();
2968-
if (HasInstantiationPayload)
2969-
{
2970-
writeSize += FastBufferWriter.GetWriteSize<int>();
2971-
writeSize += InstantiationPayload.Length;
2972-
}
29732957

29742958
if (!writer.TryBeginWrite(writeSize))
29752959
{
29762960
throw new OverflowException("Could not serialize SceneObject: Out of buffer space.");
29772961
}
29782962

2979-
if (HasInstantiationPayload)
2980-
{
2981-
writer.WriteValueSafe(InstantiationPayload.Length);
2982-
unsafe
2983-
{
2984-
writer.WriteBytes(InstantiationPayload.GetUnsafePtr(), InstantiationPayload.Length);
2985-
}
2986-
}
2987-
29882963
if (HasTransform)
29892964
{
29902965
writer.WriteValue(Transform);
@@ -3001,8 +2976,15 @@ public void Serialize(FastBufferWriter writer)
30012976
writer.WriteValue(OwnerObject.GetSceneOriginHandle());
30022977
}
30032978

3004-
// Synchronize NetworkVariables and NetworkBehaviours
2979+
// Synchronize Payload, NetworkVariables and NetworkBehaviours
30052980
var bufferSerializer = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(writer));
2981+
2982+
if (HasInstantiationPayload)
2983+
{
2984+
if (NetworkManager.Singleton.PrefabHandler.TryGetPayloadSynchronizer(Hash, out INetworkInstantiationPayloadSynchronizer synchronizer))
2985+
synchronizer.OnSynchronize(ref bufferSerializer);
2986+
}
2987+
30062988
OwnerObject.SynchronizeNetworkBehaviours(ref bufferSerializer, TargetClientId);
30072989
}
30082990

@@ -3045,34 +3027,12 @@ public void Deserialize(FastBufferReader reader)
30453027
readSize += HasTransform ? FastBufferWriter.GetWriteSize<TransformData>() : 0;
30463028
readSize += FastBufferWriter.GetWriteSize<int>();
30473029

3048-
int preInstanceDataSize = 0;
3049-
if (HasInstantiationPayload)
3050-
{
3051-
if (!reader.TryBeginRead(FastBufferWriter.GetWriteSize<int>()))
3052-
{
3053-
throw new OverflowException($"Could not deserialize SceneObject: Reading past the end of the buffer ({nameof(InstantiationPayload)} size)");
3054-
}
3055-
3056-
reader.ReadValueSafe(out preInstanceDataSize);
3057-
readSize += FastBufferWriter.GetWriteSize<int>();
3058-
readSize += preInstanceDataSize;
3059-
}
3060-
30613030
// Try to begin reading the remaining bytes
30623031
if (!reader.TryBeginRead(readSize))
30633032
{
30643033
throw new OverflowException("Could not deserialize SceneObject: Reading past the end of the buffer");
30653034
}
30663035

3067-
if (HasInstantiationPayload)
3068-
{
3069-
unsafe
3070-
{
3071-
InstantiationPayload = new FastBufferReader(reader.GetUnsafePtrAtCurrentPosition(), Allocator.Persistent, preInstanceDataSize);
3072-
reader.Seek(reader.Position + preInstanceDataSize);
3073-
}
3074-
}
3075-
30763036
if (HasTransform)
30773037
{
30783038
reader.ReadValue(out Transform);
@@ -3081,6 +3041,15 @@ public void Deserialize(FastBufferReader reader)
30813041
// The NetworkSceneHandle is the server-side relative
30823042
// scene handle that the NetworkObject resides in.
30833043
reader.ReadValue(out NetworkSceneHandle);
3044+
3045+
if (HasInstantiationPayload)
3046+
{
3047+
if (NetworkManager.Singleton.PrefabHandler.TryGetPayloadSynchronizer(Hash, out INetworkInstantiationPayloadSynchronizer synchronizer))
3048+
{
3049+
var instantiationPayloadBufferReader = new BufferSerializer<BufferSerializerReader>(new BufferSerializerReader(reader));
3050+
synchronizer.OnSynchronize(ref instantiationPayloadBufferReader);
3051+
}
3052+
}
30843053
}
30853054
}
30863055

@@ -3202,8 +3171,7 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId = NetworkManager
32023171
Hash = CheckForGlobalObjectIdHashOverride(),
32033172
OwnerObject = this,
32043173
TargetClientId = targetClientId,
3205-
HasInstantiationPayload = InstantiationPayload.IsInitialized,
3206-
InstantiationPayload = InstantiationPayload
3174+
HasInstantiationPayload = NetworkManager.PrefabHandler.HasPayloadSynchronizer(GlobalObjectIdHash),
32073175
};
32083176

32093177
// Handle Parenting
@@ -3298,11 +3266,6 @@ internal static NetworkObject AddSceneObject(in SceneObject sceneObject, FastBuf
32983266
// in order to be able to determine which NetworkVariables the client will be allowed to read.
32993267
networkObject.OwnerClientId = sceneObject.OwnerClientId;
33003268

3301-
// Even though the Instantiation Payload is typically consumed during the spawn message handling phase,
3302-
// we still assign it here to preserve the original spawn metadata for potential inspection, diagnostics,
3303-
// or in case future systems want to access it directly without relying on synchronization messages.
3304-
networkObject.InstantiationPayload = sceneObject.InstantiationPayload;
3305-
33063269
// Special Case: Invoke NetworkBehaviour.OnPreSpawn methods here before SynchronizeNetworkBehaviours
33073270
networkObject.InvokeBehaviourNetworkPreSpawn();
33083271

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ public interface INetworkInstantiationPayloadSynchronizer
1616
/// </summary>
1717
/// <param name="serializer">The buffer serializer used to read or write custom instantiation data.</param>
1818
void OnSynchronize<T>(ref BufferSerializer<T> serializer) where T : IReaderWriter;
19-
}
19+
//void Serialize(FastBufferWriter writer);
20+
//void Deserialize(FastBufferReader reader);
21+
}
2022
}

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

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using Unity.Collections;
34
using UnityEngine;
45

56
namespace Unity.Netcode
@@ -226,29 +227,33 @@ public bool RemoveHandler(uint globalObjectIdHash)
226227
/// <returns>true or false</returns>
227228
internal bool ContainsHandler(uint networkPrefabHash) => m_PrefabAssetToPrefabHandler.ContainsKey(networkPrefabHash) || m_PrefabInstanceToPrefabAsset.ContainsKey(networkPrefabHash);
228229

229-
/// <summary>
230-
/// Injects instantiation payload on the networkObject
231-
/// </summary>
232-
/// <param name="networkObject">Injection target</param>
233-
internal void InjectInstantiationPayload(NetworkObject networkObject)
230+
internal bool HasPayloadSynchronizer(uint objectHash) => TryGetPayloadSynchronizer(objectHash, out _);
231+
internal bool TryGetPayloadSynchronizer(uint objectHash, out INetworkInstantiationPayloadSynchronizer synchronizer)
232+
{
233+
if (m_PrefabAssetToPrefabHandler.TryGetValue(objectHash, out var prefabInstanceHandler))
234+
{
235+
if (prefabInstanceHandler is INetworkInstantiationPayloadSynchronizer payloadSynchronizer)
236+
{
237+
synchronizer = payloadSynchronizer;
238+
return true;
239+
}
240+
}
241+
synchronizer = null;
242+
return false;
243+
}
244+
245+
internal void ReadInstantiationPayload(uint objectHash, FastBufferReader reader)
234246
{
235-
if (m_PrefabAssetToPrefabHandler.TryGetValue(networkObject.GlobalObjectIdHash, out var prefabInstanceHandler))
247+
if (m_PrefabAssetToPrefabHandler.TryGetValue(objectHash, out var prefabInstanceHandler))
236248
{
237249
if (prefabInstanceHandler is INetworkInstantiationPayloadSynchronizer synchronizer)
238250
{
239-
var fastBufferWriter = new FastBufferWriter(16, Collections.Allocator.Temp, int.MaxValue);
240-
var instantiationPayloadBufferWriter = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(fastBufferWriter));
241-
synchronizer.OnSynchronize(ref instantiationPayloadBufferWriter);
242-
if (fastBufferWriter.Length > 0)
243-
{
244-
unsafe
245-
{
246-
networkObject.InstantiationPayload = new FastBufferReader(fastBufferWriter.GetUnsafePtr(), Collections.Allocator.Persistent, fastBufferWriter.Length);
247-
}
248-
}
251+
var instantiationPayloadBufferReader = new BufferSerializer<BufferSerializerReader>(new BufferSerializerReader(reader));
252+
synchronizer.OnSynchronize(ref instantiationPayloadBufferReader);
249253
}
250254
}
251255
}
256+
252257

253258
/// <summary>
254259
/// Returns the source NetworkPrefab's <see cref="NetworkObject.GlobalObjectIdHash"/>
@@ -279,20 +284,10 @@ internal uint GetSourceGlobalObjectIdHash(uint networkPrefabHash)
279284
/// <param name="position"></param>
280285
/// <param name="rotation"></param>
281286
/// <returns></returns>
282-
internal NetworkObject HandleNetworkPrefabSpawn<T>(uint networkPrefabAssetHash, ulong ownerClientId, ref BufferSerializer<T> InstantiationPayloadSerializer, Vector3 position, Quaternion rotation) where T : IReaderWriter
287+
internal NetworkObject HandleNetworkPrefabSpawn(uint networkPrefabAssetHash, ulong ownerClientId, Vector3 position, Quaternion rotation)
283288
{
284289
if (m_PrefabAssetToPrefabHandler.TryGetValue(networkPrefabAssetHash, out var prefabInstanceHandler))
285290
{
286-
if (InstantiationPayloadSerializer.IsReader)
287-
{
288-
FastBufferReader instantiationPayloadReader = InstantiationPayloadSerializer.GetFastBufferReader();
289-
bool ShouldSychronize = instantiationPayloadReader.IsInitialized && instantiationPayloadReader.Length > 0;
290-
if (ShouldSychronize && prefabInstanceHandler is INetworkInstantiationPayloadSynchronizer synchronizer)
291-
{
292-
synchronizer.OnSynchronize(ref InstantiationPayloadSerializer);
293-
}
294-
}
295-
296291
var networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation);
297292

298293
//Now we must make sure this alternate PrefabAsset spawned in place of the prefab asset with the networkPrefabAssetHash (GlobalObjectIdHash)

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ internal NetworkObject InstantiateAndSpawnNoParameterChecks(NetworkObject networ
749749
if (forceOverride || NetworkManager.IsClient || NetworkManager.DistributedAuthorityMode || NetworkManager.PrefabHandler.ContainsHandler(networkPrefab.GlobalObjectIdHash))
750750
{
751751
var intantiationPayloadWriter = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(new FastBufferWriter(16, Collections.Allocator.Temp, int.MaxValue)));
752-
networkObject = GetNetworkObjectToSpawn(networkPrefab.GlobalObjectIdHash, ownerClientId, ref intantiationPayloadWriter, position, rotation);
752+
networkObject = GetNetworkObjectToSpawn(networkPrefab.GlobalObjectIdHash, ownerClientId, position, rotation);
753753
}
754754
else // Under this case, server instantiate the prefab passed in.
755755
{
@@ -780,14 +780,14 @@ internal NetworkObject InstantiateAndSpawnNoParameterChecks(NetworkObject networ
780780
/// Gets the right NetworkObject prefab instance to spawn. If a handler is registered or there is an override assigned to the
781781
/// passed in globalObjectIdHash value, then that is what will be instantiated, spawned, and returned.
782782
/// </summary>
783-
internal NetworkObject GetNetworkObjectToSpawn<T>(uint globalObjectIdHash, ulong ownerId, ref BufferSerializer<T> instantiationPayloadSerializer, Vector3? position, Quaternion? rotation, bool isScenePlaced = false) where T : IReaderWriter
783+
internal NetworkObject GetNetworkObjectToSpawn(uint globalObjectIdHash, ulong ownerId, Vector3? position, Quaternion? rotation, bool isScenePlaced = false)
784784
{
785785
NetworkObject networkObject = null;
786786
// If the prefab hash has a registered INetworkPrefabInstanceHandler derived class
787787
if (NetworkManager.PrefabHandler.ContainsHandler(globalObjectIdHash))
788788
{
789789
// Let the handler spawn the NetworkObject
790-
networkObject = NetworkManager.PrefabHandler.HandleNetworkPrefabSpawn(globalObjectIdHash, ownerId, ref instantiationPayloadSerializer, position ?? default, rotation ?? default);
790+
networkObject = NetworkManager.PrefabHandler.HandleNetworkPrefabSpawn(globalObjectIdHash, ownerId, position ?? default, rotation ?? default);
791791
networkObject.NetworkManagerOwner = NetworkManager;
792792
}
793793
else
@@ -889,8 +889,7 @@ internal NetworkObject CreateLocalNetworkObject(NetworkObject.SceneObject sceneO
889889
// If scene management is disabled or the NetworkObject was dynamically spawned
890890
if (!NetworkManager.NetworkConfig.EnableSceneManagement || !sceneObject.IsSceneObject)
891891
{
892-
var instantiationPayloadReader = new BufferSerializer<BufferSerializerReader>(new BufferSerializerReader(sceneObject.InstantiationPayload));
893-
networkObject = GetNetworkObjectToSpawn(sceneObject.Hash, sceneObject.OwnerClientId, ref instantiationPayloadReader, position, rotation, sceneObject.IsSceneObject);
892+
networkObject = GetNetworkObjectToSpawn(sceneObject.Hash, sceneObject.OwnerClientId, position, rotation, sceneObject.IsSceneObject);
894893
}
895894
else // Get the in-scene placed NetworkObject
896895
{

0 commit comments

Comments
 (0)