Skill Behaviour needs to use a Coroutine, but can't be a MonoBehaviour.

So my character has a few skills equiped. He uses one of them. This is gonna loop through the behaviours in that skill. For example, it could have these 4 behaviours: you buff your attack for 1 turn, then wait for an enemy to be clicked within attack range, then attack with a 200% multiplier, and if this kills the enemy you extend that buff for 3 turns.

Skills are ScriptableObjects. For example, here’s a basic attack.

6117884--666497--upload_2020-7-22_12-10-42.png

Behaviours should be “select enemy in range”, and then “deal damage”. But extra behaviours will be added dynamically, like for example if you have a passive that says “critical hits heal you for 10% of damage dealt”, and such.
But here’s the problem. I need to be able to create these Skill Behaviours and link them to the skill SO in the editor. And at the same time they need Coroutines to actually work. Here’s an example.

But they can’t be MonoBehaviours! Otherwise I can’t assign them to the skill SO.
I’m so confused. They just need to store a little Behave function. I have a SkillHandler MonoBehaviour that loops through all behaviours on skill use - it just needs to call these Behave functions. But these behave functions can’t exist, cause they can’t use coroutines, cause SkillBehaviour can’t be a MonoBehaviour, cause I need to attach it to the skill SO.

Do you see any solution to this problem? I’m fine having to rework all the code, as long as I can get it to work. So feel free to suggest completely different ways to implement such a skill system.

Thanks a lot in advance!

You don’t need to rework. MonoBehaviour’s “StartCoroutine” method is public and can be called by any monobehaviour.
If that selection manager is MonoBehaviour you can call it like SelectionManager.StartCoroutine(coroutine here).

Oh my, this makes so much sense and completely solves all my problems. Thank you a lot!!

I prefer to make a public method on the MonoBehaviour that internally starts the coroutine. It avoids confusion about which object the coroutine is actually associated with. So in your example I would make Co_SelectEnemy a private method, and have a public method on SelectionManager called something like BeginSelectingEnemy() which internally starts the coroutine.

I agree on that. My answer was only targeted for current problem. There will be structural problems in future with calling random monobehaviours from different objects and their execution order and interruptions.

1 Like