Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Best way to add prefab to the NetworkPrefabList at runtime?

Discussion in 'Netcode for GameObjects' started by Sushi8819, Nov 19, 2023.

  1. Sushi8819

    Sushi8819

    Joined:
    Oct 20, 2023
    Posts:
    17
    I'm exploring ways to dynamically add prefabs to the networkPrefabList at runtime in Unity.
    Currently, I have come up with two methods. One is to have both all clients and the server download pre-registered data from the cloud storage when a client connect to the server, which data is small in size. Then, both the server and client dynamically generate network objects from this data using a method like addNetworkPrefabList().
    The other way is using networkObjectReference on all client sides to rewrite all network objects.

    Since the data to be downloaded cannot be added to the prefab list in advance, I am seeking advice on alternative methods to dynamically modify the content of networkObject at runtime. If you have any other good ideas, I would appreciate your advice.
    Thank you.
     
  2. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    244
    It depends upon the extent of the modifications needed and what you are trying to accomplish (over-all goal/feature) with this type of functionality. Generally speaking, after a client is connected and synchronized you would do something like:

    Code (CSharp):
    1.  
    2.         var networkPrefab = new NetworkPrefab()
    3.         {
    4.             Prefab = youNewNetworkObject,
    5.             Override = NetworkPrefabOverride.None,
    6.         };
    7.  
    You can also fiddle around with overrides as well.
    Another way to handle this is using the NetworkManager.PrefabHandler that is typically used for object pools but can be used for many other purposes. The idea here is you would need at least 1 registered NetworkPrefab per registered INetworkPrefabInstanceHandler and then 1 registered NetworkPrefab per "dynamically generated" NetworkObject.

    The issue boils down to how the GlobalObjectIdHash value is generated and when it is generated. The GlobalObjectIdHash is used when sending a CreateObjectMessage and used to determine "what to spawn" on the client side. So, just instantiating a GameObject at runtime and adding a NetworkObject component to it won't work because the GlobalObjectIdHash value is generated within the editor when the NetworkObject's OnValidate method is invoked (when it is changed or when building a stand alone binary).

    Of course, you can always use custom messages and come up with your own protocol and serialization pipeline since those don't require a NetworkObject to be able to send and receive messages. With custom named messages you could do something like:
    • Have an in-scene placed NetworkObject that acts like a "dynamic object generator".
      • This would utilize NetworkVariables and/or Rpcs to handle the initial signaling and generation of the dynamically created object.
      • Part of this process would include the "named message" (i.e. its name...could be a GUID) that clients would start listening to on the dynamically generated object. You could create two (or more) for "bi-directional" communication between server and client(s).
    • Once created, the dynamically generated object would send and receive named messages that would include serialized data that would dictate <insert some form of functionality and/or property update here>
    But it all really depends upon what you are trying to accomplish as to what would be the best fit.