Passive/Active ability system implementation

Hello all, I hope you can help me with the following.

I’m trying to create a game with an upgrade system/ability system. (RPG like)
But as I plan to create a bunch of abilities, I was wondering what the best way is to implement such system.
At the moment, I use scriptable objects to store the abilities.
These scriptable object, I collect under the Character (also a scriptable object)
But I seem to be at a loss of how to add methods on the scriptable object Ability.
Should I just create abilities under the script that creates the scriptable object and somehow create the possiblity to add those methods to the Ability? And how would I do that?

Skill.cs:

namespace GameName{
[CreateAssetMenu(menuName = "RPG Generator/Player/Create Skill")]
    public class Skills : ScriptableObject
    {
        public string Description;
        public Sprite Icon;
        public int LevelNeeded;
        public List<PlayerSkills> neededUpgrades = new List<PlayerSkills>();
        public List<PlayerSkills> atleastOneOfTheseUpgrades = new List<PlayerSkills>();
    }
}

Character.cs:

namespace GameName
{
    [CreateAssetMenu(menuName = "RPG Generator/Player/Create Character")]
    public class Character : ScriptableObject
    {
        public new string name;
        public Sprite thumbnail;
        public int currentEnergy;
        public int currentXP;
        public int level;
        public int maxEnergy;
        public int nextNeededXP;
        public int startingEnergy;
        public List<UpgradedSkills> hasTheseUpgrades = new List<UpgradedSkills>();

        public void SetXPLevel()
        {
            int tempXPNextLevel = 272;
            for (int x = 0; x < level; x++)
            {
                tempXPNextLevel = (int)(tempXPNextLevel * 1.1f);
            }
            nextNeededXP = tempXPNextLevel;
        }

    }

PublicMethods.cs

namespace GameName
{

    [System.Serializable]
    public class PlayerSkills
    {
        public Skills skill;

        public PlayerSkills(Skills skill)
        {
            this.skill = skill;
        }
    }

    [System.Serializable]
    public class UpgradedSkills
    {
        public Skills skill;
        public int skillLevel;

        public UpgradedSkills(Skills skill, int skillLevel)
        {
            this.skill = skill;
            this.skillLevel = skillLevel;
        }
    }
}

So for an example. If in game, I want to activate function:

public void FirstSkill()
{
Debug.Log("Yes, I feel stronger! Though this ability doesn't do anything");
}

Where do I place this code and how do I connect 1 of multiple skills to this Method.
Any ideas?
I tried several online tutorials, but none really got me where I want to be.

Just for some more clarity about the project:
I’m trying to create a sort of mix of Yahtzee and RPG elements. What I’m trying now for instance, is making a dice worth more if you upgraded the ability for it. So for instance, the number 1 on the dice is now worth another point if you score it, which can happen when you try to score the Ones, but also at Three-of-a-kind, at Four-of-a-kind and at Chance. But shouldn’t trigger on any of the others, even when used to achieve it (like Yahtzee for instance)

First of all, I wouldn’t worry about following such a strict template if you’re just starting out. I would suggest getting some skills to activate however you can, and then fit them to your character controller.

Second, you should probably write your own character controller, even if you’re planning on using one you bought. You’ll learn a lot that way, and you’ll understand the code you’re working with better, so you’ll know how to activate your skills, etc.

Third, what do you want your first skill to do? Is there an animation involved? Do you need a hit box trigger enabled? Are there any visual/sound effects involved? Is the ability triggered on button press or do you wait for the dice to roll?

Here is some pseudocode that might help you get started:

// If you want to activate ability on key press
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            skill1();
        }
    }

    private void skill1()
    {
        // Trigger animation event
        // enable hit box trigger
        // play audio/visual effect
    }
// If you want to wait until dice roll finishes
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            StartCoroutine(RollDice());
        }
    }

    private void skill1(int dmg)
    {
        // Trigger animation event
        // enable hit box trigger
        // play audio/visual effect
        // inflict damage or whatever
    }

    IEnumerator RollDice()
    {
        // animate dice roll
        // set animation event to trigger a bool "doneRolling"
        yield return new WaitUntil(() => doneRolling);
        int damage = diceRoll * 5;
        skill1(damage);
        yield break;
    }

Hello Tarball, thanks for replying.

First or my answers:

I guess you’re right and that I should just try and get it working the ways I already know how. I already have a gamemanager and a scoretracker (which houses most of the functions behind the scoring)

For character control, well, see my former answer I guess.

For functions already build (yes, by me, I haven’t bought anything, wasn’t planning on either to be honest, as I want to learn to do it myself) I have the general controls of yahtzee build (rolling dice, scoring a field, locking dice, etc.)
My first abilities which I want to enable are/is the given example “a diceroll of 1 counts for more for the scoring part”, and this might come as a shock, the upcoming abilities after that are, “a diceroll of 2 counts for more for the scoring part”, “a diceroll of 3 counts for more for the scoring part”, etc. :p. I know how to program it in a bit of a filthy way I guess, but wanted to try and do it in a way that will save me time later.
like, in a way that can look at if a certain function is being called and then adding functionality to that function somehow.

For instance I have the follwing code in LeftScoring.cs

public class LeftScoring : ScoreField
{
public override void ScoreNumber(int number)
{
base.ScoreNumber(number);
LeftSubScoring();
BonusCheck();
TotalScore();

}

No need to go into details in these functions, they work like I want them to. (for now :slight_smile: )
This peace of code is executed when pressing the correct field/button where you want to score the dice (the number is input in the Button part in Unity itself so I could use the same code for 1 trough 6)

For what I have in mind is that at initial startup of the screen (with the playerinfo loaded into the GUI, this part works), the upgrades would form a list, or lists of functions to execute (as multiple upgrades might influence 1 scoringField). Then, when activating the function, 1 extra function would be called that checks if the player has any functions active that might influence the outcome… but maybe I’m looking too much into it.

For now, I’ll just try coding the way I know how and stop the block I’m putting up for myself I guess :).

Yet, here is the function I guess would be applied to the formerly shown function ScoreNumber

public class LeftScoring : ScoreField
{
public override void ScoreNumber(int number)
{
base.ScoreNumber(number);
CheckForUpgradeInfluence(); // this is the new part
LeftSubScoring();
BonusCheck();
TotalScore();

}

public override void CheckForUpgradeInfluence()
{
for(x=0;x<UpgradesListThatMatterHere.Count;x++){
execute UpgradesListThatMatterHere[0];
}
}
}

But how to fill List with references to functions or actual functions and how to actually execute them… that I don’t know yet.