Search Unity

Resolved How do I Spawn a Network Object with scriptable object data attached to it?

Discussion in 'Netcode for GameObjects' started by CptMarvel21, May 9, 2022.

  1. CptMarvel21

    CptMarvel21

    Joined:
    Sep 18, 2021
    Posts:
    12
    I've been trying to figure out how to spawn an object to the network with its scriptable object data. Only the host sees the scriptable object data but none of the clients do. IS it not possible to spawn an object with a scriptable object attached to it?
     
  2. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    Out of the box this is not possible. Here is how I would approach this. Give each of your scriptable object an index by storing it in an array on a manager. Use a NetworkVariable<int> to synchronize the index of the data and on the other side you can use the OnValueChanged callback of the network variable and read the int and find the corresponding data for it.
     
  3. gamedevjake

    gamedevjake

    Joined:
    Aug 16, 2022
    Posts:
    26
    Thanks for this suggestion! Is there an example you could direct us to? I'm not sure how to store Scriptable Objects into an array, in particular, since my SOs are created as .asset files and not C# objects.
     
  4. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    258
    To gain access to the ScriptableObjects something like this:
    Code (CSharp):
    1. public class ScriptableObjectList : MonoBehaviour
    2. {
    3.     public List<ScriptableObject> PrefabSpawnData;
    4. }
    Will yield something like this in the inspector view:
    upload_2023-11-2_18-46-47.png

    Of course, your list should be of your ScriptableObject derived type (or base type) to make it easier to add things to it.

    To tie this together and use it with a NetworkBehaviour derived class, you could do something like this:
    Code (CSharp):
    1.  
    2. public class SomeNetworkPrefabBehaviour : NetworkBehaviour
    3. {  
    4.     public List<ScriptableObject> PrefabSpawnData;
    5.     private NetworkVariable<int> m_Configuration = new NetworkVariable<int>(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
    6.     public override void OnNetworkSpawn()
    7.     {
    8.         if (IsServer)
    9.         {
    10.             // Not sure how you determine the configuration so I am just picking a random value
    11.             m_Configuration.Value = Random.Range(0, PrefabSpawnData.Count);          
    12.         }
    13.         else
    14.         {
    15.             // If you want to change configurations "on the fly"
    16.             m_Configuration.OnValueChanged += OnConfigChanged;          
    17.         }
    18.         // Both server and clients then just configure the newly spawned instance based on the index value assigned.
    19.         InitFromData(m_Configuration.Value);
    20.         base.OnNetworkSpawn();
    21.     }
    22.    
    23.     // If you want to change configurations "on the fly"
    24.     private void OnConfigChanged(int previous, int current)
    25.     {
    26.         InitFromData(current);
    27.     }
    28.  
    29.     // Have a common place that takes the index value, gets the ScriptableObject, and then configures the instances based on the SO's properties.
    30.     private void InitFromData(int index)
    31.     {
    32.         // Initialize your prefab from this (might want to bounds check the index value, just an example)
    33.         var configData = PrefabSpawnData[index];
    34.         // (use values from configData to finish initializing your instance from this point forward)
    35.        
    36.     }
    37. }
    Or you could have your PrefabSpawnData ScriptableObject list on some other global object... just depends upon what you are trying to do (i.e. one big master list, unique lists per network prefab, etc.).

    Does this help?
     
    RikuTheFuffs-U likes this.