Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3ff9326
feat: Network Object Instantiation Payload
Extrys Apr 27, 2025
7f395ba
Merge branch 'Unity-Technologies:develop-2.0.0' into develop-2.0.0
Extrys Apr 27, 2025
f0d49aa
insight on INetworkInstantiationPayloadSynchronizer in the INetworkPr…
Extrys Apr 27, 2025
3f34e83
cleaning diff
Extrys Apr 27, 2025
47680f5
Some fixes for object instantiated in the server without handler
Extrys Apr 27, 2025
b8765a2
Merge branch 'Unity-Technologies:develop-2.0.0' into develop-2.0.0
Extrys Apr 28, 2025
de9fc05
Simplified approach that reuses createObjectMesage bufferSerializer
Extrys Apr 29, 2025
6419ad0
commented non generic serialization methods
Extrys Apr 29, 2025
1d746fe
Merge branch 'feat/InstantiationPayload' into develop-2.0.0
Extrys Apr 29, 2025
4005c50
Cleaning diff
Extrys Apr 29, 2025
a103e49
Cleaning diff
Extrys Apr 29, 2025
43e8ff4
Review Changes
Extrys Apr 30, 2025
0fab0a6
Some more renamigs for making it more closer to unity's naming
Extrys Apr 30, 2025
36a041c
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys May 1, 2025
fd787e8
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys May 2, 2025
96b7af6
Added buffer safety and Tests
Extrys May 5, 2025
e49cb63
Merge remote-tracking branch 'origin/develop-2.0.0' into develop-2.0.0
Extrys May 5, 2025
89eb5c4
Log text change for more clarity
Extrys May 5, 2025
adead9d
Renamed HasInstantiationPayload to HasInstantiationData to mantain na…
Extrys May 5, 2025
e4481b2
CHANGELOG.md entry added
Extrys May 5, 2025
3522fc0
Merge branch 'Unity-Technologies:develop-2.0.0' into develop-2.0.0
Extrys May 5, 2025
6757e63
Solved late-join problems
Extrys May 6, 2025
a5670e3
cleaning diff
Extrys May 6, 2025
426d82c
Updated comment
Extrys May 6, 2025
6899764
Added more Buffer/Synchronization safety changes
Extrys May 6, 2025
c1d6503
Improves handler lookup performance
Extrys May 6, 2025
096c85c
New stateless approach working flawless
Extrys May 8, 2025
7f6c9c7
Test updated
Extrys May 8, 2025
89dd4c0
Test refactor and included late joining test
Extrys May 8, 2025
b992b7c
clean diff
Extrys May 8, 2025
1f27a68
Changelog updated
Extrys May 8, 2025
5b68637
Adds comment for data handling workaround
Extrys May 9, 2025
d42bf95
Cleaning diff, fixed comment accidentally using a chinese version of …
Extrys May 9, 2025
4c7f63d
New requirements fullfilled
Extrys May 12, 2025
2b6befd
removed yet unused method
Extrys May 12, 2025
3dea6aa
extending the interface to directly allow different injection patterns
Extrys May 12, 2025
015e384
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys May 14, 2025
536642b
Pure stateless, non generic approach for sending data through fastBuf…
Extrys May 16, 2025
fa774e7
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys May 16, 2025
0d62ea4
renamings from Inject to Set
Extrys May 16, 2025
3fad66c
Inlined functions and removed terniary call
Extrys May 24, 2025
81d574a
Changed instantiation data throw by an error log
Extrys May 24, 2025
36ec35f
Abstract class approach, removed wrapper
Extrys May 24, 2025
7326a83
Removed the BufferSerializer From the GetInstantiationDataReader method
Extrys May 24, 2025
e8a661c
Using Approach A (unsafe block) to avoid allocations for FastBufferRe…
Extrys May 28, 2025
f47f3d4
Most review comments addressed
Extrys May 28, 2025
6b3963f
Renamed Interface in the Changelog
Extrys May 29, 2025
fc43642
Update formatting and use NetcodeIntegrationTest for test class
EmandM May 30, 2025
729f4d6
fixed late join bug
Extrys May 30, 2025
fea9d7d
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys May 30, 2025
900c7ee
Using BytePacker utilities to optimize the size of the serialized int…
Extrys May 30, 2025
886697e
Updated comment to match new interface name
Extrys Jun 6, 2025
4586a6e
Merge branch 'develop-2.0.0' into develop-2.0.0
Extrys Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2882,6 +2882,12 @@ public bool SpawnWithObservers
set => ByteUtility.SetBit(ref m_BitField, 10, value);
}

public bool HasInstantiationPayload
{
get => ByteUtility.GetBit(m_BitField, 11);
set => ByteUtility.SetBit(ref m_BitField, 11, value);
}

// When handling the initial synchronization of NetworkObjects,
// this will be populated with the known observers.
public ulong[] Observers;
Expand Down Expand Up @@ -2970,8 +2976,15 @@ public void Serialize(FastBufferWriter writer)
writer.WriteValue(OwnerObject.GetSceneOriginHandle());
}

// Synchronize NetworkVariables and NetworkBehaviours
// Synchronize Payload, NetworkVariables and NetworkBehaviours
var bufferSerializer = new BufferSerializer<BufferSerializerWriter>(new BufferSerializerWriter(writer));

if (HasInstantiationPayload)
{
if (NetworkManager.Singleton.PrefabHandler.TryGetPayloadSynchronizer(Hash, out INetworkInstantiationPayloadSynchronizer synchronizer))
synchronizer.OnSynchronize(ref bufferSerializer);
}

OwnerObject.SynchronizeNetworkBehaviours(ref bufferSerializer, TargetClientId);
}

Expand Down Expand Up @@ -3028,6 +3041,15 @@ public void Deserialize(FastBufferReader reader)
// The NetworkSceneHandle is the server-side relative
// scene handle that the NetworkObject resides in.
reader.ReadValue(out NetworkSceneHandle);

if (HasInstantiationPayload)
{
if (NetworkManager.Singleton.PrefabHandler.TryGetPayloadSynchronizer(Hash, out INetworkInstantiationPayloadSynchronizer synchronizer))
{
var instantiationPayloadBufferReader = new BufferSerializer<BufferSerializerReader>(new BufferSerializerReader(reader));
synchronizer.OnSynchronize(ref instantiationPayloadBufferReader);
}
}
}
}

Expand Down Expand Up @@ -3148,7 +3170,8 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId = NetworkManager
NetworkSceneHandle = NetworkSceneHandle,
Hash = CheckForGlobalObjectIdHashOverride(),
OwnerObject = this,
TargetClientId = targetClientId
TargetClientId = targetClientId,
HasInstantiationPayload = NetworkManager.PrefabHandler.HasPayloadSynchronizer(GlobalObjectIdHash),
};

// Handle Parenting
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Unity.Netcode
{
/// <summary>
/// Interface for synchronizing custom instantiation payloads during NetworkObject spawning.
/// Used alongside <see cref="INetworkPrefabInstanceHandler"/> to extend instantiation behavior.
/// </summary>
public interface INetworkInstantiationPayloadSynchronizer
{
/// <summary>
/// Provides a method for synchronizing instantiation payload data during the spawn process.
/// Extends <see cref="INetworkPrefabInstanceHandler"/> to allow passing additional data prior to instantiation
/// to help identify or configure the local object instance that should be linked to the spawned NetworkObject.
///
/// This method is invoked immediately before <see cref="INetworkPrefabInstanceHandler.Instantiate"/> is called,
/// allowing you to cache or prepare information needed during instantiation.
/// </summary>
/// <param name="serializer">The buffer serializer used to read or write custom instantiation data.</param>
void OnSynchronize<T>(ref BufferSerializer<T> serializer) where T : IReaderWriter;
//void Serialize(FastBufferWriter writer);
//void Deserialize(FastBufferReader reader);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public interface INetworkPrefabInstanceHandler
///
/// Note on Pooling: If you are using a NetworkObject pool, don't forget to make the NetworkObject active
/// via the <see cref="GameObject.SetActive(bool)"/> method.
///
/// If you need to pass custom data at instantiation time (e.g., selecting a variant, setting initialization parameters, or choosing a pre-instantiated object),
/// implement <see cref="INetworkInstantiationPayloadSynchronizer"/> alongside this interface to receive the data before instantiation.
/// </summary>
/// <param name="ownerClientId">the owner for the <see cref="NetworkObject"/> to be instantiated</param>
/// <param name="position">the initial/default position for the <see cref="NetworkObject"/> to be instantiated</param>
Expand Down Expand Up @@ -223,6 +226,33 @@ public bool RemoveHandler(uint globalObjectIdHash)
/// <returns>true or false</returns>
internal bool ContainsHandler(uint networkPrefabHash) => m_PrefabAssetToPrefabHandler.ContainsKey(networkPrefabHash) || m_PrefabInstanceToPrefabAsset.ContainsKey(networkPrefabHash);

/// <summary>
/// Check to see if a <see cref="NetworkObject.GlobalObjectIdHash"/> is registered to an <see cref="INetworkInstantiationPayloadSynchronizer"/> implementation
/// </summary>
/// <param name="objectHash"></param>
/// <returns></returns>
internal bool HasPayloadSynchronizer(uint objectHash) => TryGetPayloadSynchronizer(objectHash, out _);

/// <summary>
/// Returns the <see cref="INetworkInstantiationPayloadSynchronizer"/> implementation for a given <see cref="NetworkObject.GlobalObjectIdHash"/>
/// </summary>
/// <param name="objectHash"></param>
/// <param name="synchronizer"></param>
/// <returns></returns>
internal bool TryGetPayloadSynchronizer(uint objectHash, out INetworkInstantiationPayloadSynchronizer synchronizer)
{
if (m_PrefabAssetToPrefabHandler.TryGetValue(objectHash, out var prefabInstanceHandler))
{
if (prefabInstanceHandler is INetworkInstantiationPayloadSynchronizer payloadSynchronizer)
{
synchronizer = payloadSynchronizer;
return true;
}
}
synchronizer = null;
return false;
}

/// <summary>
/// Returns the source NetworkPrefab's <see cref="NetworkObject.GlobalObjectIdHash"/>
/// </summary>
Expand Down