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?
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 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.
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.
To gain access to the ScriptableObjects something like this:
public class ScriptableObjectList : MonoBehaviour
{
public List<ScriptableObject> PrefabSpawnData;
}
Will yield something like this in the inspector view:
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:
public class SomeNetworkPrefabBehaviour : NetworkBehaviour
{
public List<ScriptableObject> PrefabSpawnData;
private NetworkVariable<int> m_Configuration = new NetworkVariable<int>(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
public override void OnNetworkSpawn()
{
if (IsServer)
{
// Not sure how you determine the configuration so I am just picking a random value
m_Configuration.Value = Random.Range(0, PrefabSpawnData.Count);
}
else
{
// If you want to change configurations "on the fly"
m_Configuration.OnValueChanged += OnConfigChanged;
}
// Both server and clients then just configure the newly spawned instance based on the index value assigned.
InitFromData(m_Configuration.Value);
base.OnNetworkSpawn();
}
// If you want to change configurations "on the fly"
private void OnConfigChanged(int previous, int current)
{
InitFromData(current);
}
// Have a common place that takes the index value, gets the ScriptableObject, and then configures the instances based on the SO's properties.
private void InitFromData(int index)
{
// Initialize your prefab from this (might want to bounds check the index value, just an example)
var configData = PrefabSpawnData[index];
// (use values from configData to finish initializing your instance from this point forward)
}
}
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?