Specify GlobalObjectIdHash at runtime (for procedurally generated prefabs)
Is your feature request related to a problem? Please describe.
I would like to generate prefabs procedurally at runtime.
I can easily register them with NetworkManager.PrefabHandler.AddHandler.
The only missing part is that I can't set NetworkObject.GlobalObjectIdHash because it's internal.
Describe the solution you'd like
I understand exposing NetworkObject.GlobalObjectIdHash might be a problem (it's advanced use case and if public on NetworkObject, user might think it's OK to edit it in typical scenario).
Maybe adding it in a more specific location such as a method in NetworkPrefabHandler would be very helpful.
Describe alternatives you've considered Currently I use reflection to set it...
Added into product backlog for consideration, MTTH-124
After seeing #2565, I wanted to add two more details to my use case:
- I add prefab after
NetworkManager.Initialize() - #2565 unit test also set
GlobalObjectIdHashjust like I would like to do, but since it's internal I can't do it the same way.
Would it be possible to simply add a function like NetworkObject.SetRuntimeGlobalObjectIdHash() (I understand the GlobalObjectIdHash itself is probably better as non-public to not encourage user to edit it, and rather use a function name with Runtime to show it only make sense when creating runtime prefab).
If that approach sounds OK, I would be happy to submit a PR.
What I do is something like this:
// Note: I make sure prefab handler and IDs match on both client and server
var handler = new VehicleNetworkPrefabInstanceHandler(prefabHandlerId++);
networkGame.NetworkManager.PrefabHandler.AddHandler(handler.Id, handler);
internal class VehicleNetworkPrefabInstanceHandler : INetworkPrefabInstanceHandler
{
public VehicleNetworkPrefabInstanceHandler(uint id)
{
Id = id;
}
public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation)
{
// Create NetworkObject
var networkObject = vehicleInstance.AddComponent<NetworkObject>();
// NOT POSSIBLE (I currently use reflection)
networkObject.GlobalObjectIdHash = Id;
return networkObject;
}
public void Destroy(NetworkObject networkObject) {}
}
@virgile-wp, you saved my day with your code, thanks!