Skip to content

feat: Allow to pass custom data on Spawn calls #3419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: release/2.3.3
Choose a base branch
from

Conversation

Extrys
Copy link

@Extrys Extrys commented Apr 23, 2025

This PR introduces support for passing custom spawn data from the server to clients during the spawn process of a NetworkObject.
This enables deterministic instantiation or contextual setup on the client without relying on RPCs or external sync steps.

Doesn't break or invalidate existing user code
the feature is fully optional and designed via an extension interface to preserve full backward compatibility.

Changelog

  • Added: INetworkCustomSpawnDataReceiver interface to allow reading custom spawn data on the client side.
  • Changed: CreateObjectMessage now includes optional CustomSpawnData handling.
  • Changed: Involved spawn methods now includes optional CustomSpawnData parameter.

Testing and Documentation

  • No tests have been added.

Deprecated API

  • No APIs were deprecated in this PR.

Backport

  • No backport required. This is a new feature for the current development version only.

Implementation example

public class SyncedPrefabInstanceHandler : NetworkBehaviour, INetworkPrefabInstanceHandler, INetworkCustomSpawnDataReceiver
{
	public GameObject basePrefab;
	public NetworkObject basePrefabN;

	public GameObject[] prefabs;

	public override void OnNetworkSpawn()
	{
		NetworkManager.AddNetworkPrefab(basePrefab);
		NetworkManager.PrefabHandler.AddHandler(basePrefab, this);
	}
	public override void OnNetworkDespawn()
	{
		NetworkManager.PrefabHandler.RemoveHandler(basePrefab);
		NetworkManager.RemoveNetworkPrefab(basePrefab);
	}

       //See how i send custom data on the spawn
	public void Spawn(int metadata)
	{
		NetworkManager.SpawnManager.InstantiateAndSpawn(basePrefabN, customSpawnData: new byte[] { (byte)metadata});
	}

	int spawnData;
        // Implementing the INetworkCustomSpawnDataReceiver, i can catch this custom data just before the instantiate
	public void OnCustomSpawnDataReceived(byte[] customSpawnData)
	{
		Debug.Log("${nameof(SyncedPrefabInstanceHandler)}: Received custom spawn data: " + customSpawnData[0]);
		spawnData = customSpawnData[0];
	}
    
        //in the instantiate i use the custom spawn data allow looking for preinstantiated instances or spawning compatible arbitrary prefabs by id
	public NetworkObject Instantiate(ulong clientId, Vector3 position, Quaternion rotation)
	{
		return Instantiate(prefabs[spawnData], position, rotation).GetComponent<NetworkObject>();
	}

	public void Destroy(NetworkObject networkObject)
	{
		GameObject.Destroy(networkObject.gameObject);
	}
}```

@Extrys Extrys requested review from NoelStephensUnity, EmandM and a team as code owners April 23, 2025 17:35
@unity-cla-assistant
Copy link

unity-cla-assistant commented Apr 23, 2025

CLA assistant check
All committers have signed the CLA.

@Extrys Extrys changed the title Release/2.3.3 feat: Allow to pass custom data on Spawn calls Apr 23, 2025
@EmandM
Copy link
Collaborator

EmandM commented Apr 23, 2025

Thank you for your contribution!

At this time, we would rather avoid adding parameters to the Spawn(), SpawnWithOwnership() and SpawnPlayerObject() methods. These are very high traffic methods and it is very easy for feature creep to happen in these places. This approach also introduces the potential for strange side effects around in scene placed Network Objects.

Could an approach like the NetworkBehaviour.OnSynchronize() method work for your use case? It might be easier if you could open an issue on this topic so we can discuss the use case more in-depth.

@Extrys
Copy link
Author

Extrys commented Apr 23, 2025

Thank you for your contribution!

At this time, we would rather avoid adding parameters to the Spawn(), SpawnWithOwnership() and SpawnPlayerObject() methods. These are very high traffic methods and it is very easy for feature creep to happen in these places. This approach also introduces the potential for strange side effects around in scene placed Network Objects.

Could an approach like the NetworkBehaviour.OnSynchronize() method work for your use case? It might be easier if you could open an issue on this topic so we can discuss the use case more in-depth.

thanks for the feedback! i will open an issue regarding my use case

there is currently a forum post on unity i made for it, which is this
https://discussions.unity.com/t/allow-passing-spawn-metadata-to-instantiate-via-prefabhandler/1630903/2

I might copiy this into an issue to see if there is a pleasing solution

here is the issue i created
#3421

Also would it help if it were a new method instead of adding a parameter to the original method?
something like InstantiateAndSpawnWithCustomData(indexOfPrefabHandler, customSpawnData)

Perhaps I could explore introducing a kind of spawn builder system where the Spawn() methods remain untouched, but external data can be attached through a chainable builder pattern. This would preserve the current API while allowing advanced usage patterns without impacting existing workflows or causing order issues

Another idea I’d like to experiment with is decoupling the INetworkPrefabInstanceHandler from prefabs entirely, so it acts more like a general-purpose "Spawner" rather than being strictly tied to prefab references

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants