(ScriptableObject = SO)
I've recently been trying to learn about ScriptableObjects and have set up a project in Unity where I simply want to shoot incoming enemies that spawn. I have set it up so I can create different enemies through the SO:s but noticed that I still need to create a prefab for every single enemy. Therefore after not much luck googling I wanted to ask if there is a way to load in specific SO:s for every enemy spawned?
Say I have a spawnmanager that is spawning different enemies depending on their % to spawn. Is it possible in run-time through scripts check the probability for which enemy to spawn and then load/find that specific data created through SO:s?
TLDR : use Monobehvaiour to implement an enemy. Use SO just to setup its data or to implement part of its logic. So it's better not to spawn one SO per enemy. You spawn enemy as prefab and in their prefab you may add one or more SO to achieve composition.
To understand this I can explain the history of the SO, so you can find all the usual implementations.
Phase 1 - Data Container
Initially SO was made to store (non mutable) data. They could work as TEMPLATES.
IE, you have one Weapon SO and you instantiate it one for each weapon. In this way you can just attach the weapon to an unit.
Some nice tutorials about SO used for data are these: Customising UI With Scriptable Objects
Phase 2 - SO Logic for composition
After phase 1, someone noted that SO may be used for many different things. So many developers started adding logic inside the SO.
Doing so you can decouple a great deal of logic from the monobehaviour and attach any logic on the SO itself. You won't have one monobehaviour enemy with 2 derived class enemyWithAxe and enemyWithSword. You will have one Monobehaviour enemy and you may attach weaponAxe or weaponSword.
A great source to understand this logic and apply event to AI is this series of tutorials. Pluggable Ai With Scriptable Objects
Phase 3 - Reactive Scriptable Objects
And in the end we had this new way of using Scriptable objects described at Unite Austin 2017.
This is more advanced that the other ideas, and requires to understand the Observer pattern and the C# event system, but it is a great way to use scriptable objects.
This might be used as spawner.
SO are great to implement OOP pattern I'm still not sure what will be their future with the new ECS, but I hope there will be a place for them too.
In Conclusion
I'm a great fan of SO, but there are a few cases where you want to spawn one SO for enemy. And anyway SO shouldn't replace MonoBehaviours everywhere. I would use a MonoBehaviour to represent an enemy.
If you still need to have one SO for each monobehaviour you may create them with ScrictableObject.CreateInstance at awake, but in this case they won't be much different from a base serializable class.
Still you may implement SO to setup its data (such as health or weapon damage), to handle part of its logic (such as adding effect to each weapon), or to handle the event of the spawn mechanics. I strongly suggest to give a look at the links I shared here. Choose where to start based on your experience, Phase 1 videos are the easier while Phase 3 are the most advanced. (Anyway all of them are easy enough, only the last one requires to understand the event of c#)