Is there a framework or open source project where I can have ScriptableObjects with components?

I just want a ScriptableObject that can hold data in components. I know this can be achieved by using GameObject-MonoBehaviours but this is too heavy. I need the flexibility of having data as components which I would then mix and match to model something. I don’t want to use inheritance.

I know this can be achieved DIY by using SerializeReference and a custom editor code but I want to know if there’s already an existing one.

I’m curious what you’re trying to do… this has XY Problem written all over it.

About the closest thing you might manage easily is a ScriptableObject that has references to other ScriptableObjects in it and those are used to configure the behaviour of other Components that you attach to GameObjects by giving the Component a direct reference to the appropriate ScriptableObject when you create the GameObject / Component.

An example might be an NPC definition ScriptableObject.

It would have a ScriptableObject slot defining the type of weapon the NPC carries.

When you instantiate the NPC and its gets its WeaponController Component attached, that Component would receive a reference to whatever weapon that NPC is supposed to have.

To effect the above, I like this pattern to keep things clean and flowing in one direction:

Factory Pattern in lieu of AddComponent (for timing and dependency correctness):

1 Like

The problem with an SO refencing other SO is that you can’t see them in a single inspector like how multiple MonoBehaviour does. I just wanted to model data with components. This has a lot of advantages, flexibility of modeling data being one.

Unity SerializeReferenceExtensions is one such solution.

It would allow you to do this:

[CreateAssetMenu]
public sealed class DataContainer : ScriptableObject
{
	[SerializeReference, SubclassSelector] IData[] datas;

	public TData GetData<TData>() where TData : IData
	{
		foreach(var data in datas)
		{
			if(data is T result)
			{
				return result;
			}
		}

		return null;
	}
}

The easiest solution for you would be using the Odin Inspector. With the simple attribute [InlineEditor] you can do exactly that:

1 Like