- Home /
How to Store and Reference Skills Flexibly?
This is a mix of game design best practice and code question I guess.
My issue in brief: I'm struggling to find an elegant way to dynamically referece and grant skills during runtime of the game.
What I've got are player "Skills". These can be anything from a simple stat bonus granted, to giving an ability, and many, many more unique things that change how the game world reacts to the character. Skills can be granted to the player character, enemies, even inanimate objects thanks to them all inheriting from a common controller source.
What I've tried:
Using Scriptable Objects: Felt good at first, but due to how different the skills could be from one another required constant inheritance of the SO, often meaning I had to write a single parent for a single instance for almost every single skill, which would lead to a ton of bloat.
Using an Abstract Class: Not quite as convenient as SOs, but functional. The problem I run into here is referencing the child classes. Since they're full MonoBehaviors, they have to be in the scene to reference them, which means having an empty GameObject that's just shoved full of hundreds of skills. This doesn't look or feel right to me, but it could just be my inexperience in Unity- is this normal?
Using non-Monobehavior Abstract Class: I had this idea yesterday, that I would simply use a non-MB class which I thought would let me reference them easier. However, I can't figure out how to reference a class like this that isn't Static. It obviously can't be Static because Abstract classes can't be.
Does anyone have any ideas for me? Am I missing something simple? Is option 2 just best practice even though it feels so strange and clunky? Really any help or advice would be extremely appreciated.
Worth adding probably: Each "Skill" has an abstract method "OnSkillGranted()" which is filled out by the inheriting class that makes up the actual skill. This method deter$$anonymous$$es what happens when the skill is granted. Other than that, they contain a reference to the character that's being given the skill and a few other variables (icon, name, etc) and that's all.
Perhaps this will help you Ability System with Scriptable Objects
So as I mentioned ScriptableObjects are super convenient because of how easy they are to reference and use outside the scene. However, I'm talking about a magnitude of hundreds of skills all doing varying things; unfortunately, there's no way to really have that many SO's that do diverse things while still being able to be contained in lists together and referenced interchangeably for example. You can inherit SO's but due to their limitations it's a pain, and I would have to have dozens if not hundreds of child SO types followed by the actual SOs.
To put it more clearly, if I made a parent SO 'Skill' with an abstract OnSkillGranted(), I would then make child SOs. So let's say the first skill increases player health by 10. So I would write HealthIncreaseSkill SO. Then I would Create a new HealthIncrease SO in assets to implement it. Then I need to make one that makes you friendly with a faction. FactionFriendly SO, then create it in assets to implement it. Then I need to make one that lets you use a certain type of weapons... you see where this is going. Unlike a regular script where you just write it once, for SO's there's double the time spent because you have to write the script then create the actual asset. For dozens of abilities I'd only have one asset per script, which is a huge amount of needless overhead.