Best approach to coding a Skill Tree?

Hi! I am a relatively new/on and off coder on Unity, and I wanted to work on a bit of a bigger RPG project. As part of this project, I want to include a Skill Tree. I was wondering what the best approach would be to managing the different skills? My current idea is creating a custom class for a skill that takes in parameters like the skill hotkey, prerequisite skills, etc. along with the actual function that triggers the skill (ex. instantiates and shoots a fireball). Then, for each skill, I could create a new script where I actually put the code for the corresponding function and create a reference to the class. It looks like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using System;

public class bombSkill : MonoBehaviour
{
    public GameObject bomb;
    public Transform attackPoint;
    public Transform cam;

    public float bombForwardForce;
    public float bombUpForce;
    public float bombTimer;
    public KeyCode hotkey;
    public List<Skill> prereqskills;
    public List<int> prereqstats;
    public Button bombButton;

    private Skill BombSkill;

    // Start is called before the first frame update
    void Start()
    {
        BombSkill = new Skill(false, KeyCode.R, "bomb", new List<Skill>(), new List<int>(), 2f, throwBomb, bombButton);
        bombButton.GetComponentInChildren<Text>().text = BombSkill.skillName;
    }

    // Update is called once per frame
    void Update()
    {
        if ((Input.GetKey(BombSkill.hotkey)) && (bombTimer <= 0f) && (BombSkill.unlocked)) {
            throwBomb();
        }
    
        if (bombTimer > 0) {
            bombTimer -= Time.deltaTime;
        }
    }

    public void throwBomb() {
        GameObject projectile = Instantiate(bomb, attackPoint.position, cam.rotation);
        Vector3 forceDirection = cam.transform.forward;
        RaycastHit hit;

        if (Physics.Raycast(cam.position, cam.transform.forward, out hit, 500f)) {
            forceDirection = (attackPoint.position - hit.point).normalized;
        }

        projectile.GetComponent<Rigidbody>().AddForce(cam.transform.forward * bombForwardForce + transform.up * bombUpForce, ForceMode.Impulse);

        bombTimer = BombSkill.cooldown;
    }
}

The only issue is, I saw somewhere that multiple MonoBehaviours can slow down a program dramatically, and I’m planning to have a lot of skills for this. Are there any alternative approaches? Should I put all the skills in one script? I considered Scriptable Objects, but custom classes seemed easier so I could more easily attach the function for each skill in its own script. I am very inexperienced, so any (relatively simple) explanation or suggestion would be much appreciated!

There was a lot of talk on a skill system just a few days ago: https://discussions.unity.com/t/951971

A skill tree is just a layer on top of the skills themselves. Really it’s just a data structure to record what skills have been unlocked and provide a path in which they can be unlocked, and is represented to the player via UI (the data and UI should be separate). Though it’s hard to distill down super simple as it’s not really simple/beginner stuff. Though it is something where learning C# in general will be more helpful than normal. At the very least, look into how to code a tree-like data structure.

You need numbers in the thousands to start causing this. A few monobehaviours won’t hurt anyone.

That said for a skill system, usually scriptable objects/plain C# objects provide more flexibility, as it’s all scene-independant stuff, so doesn’t need to be on a prefab.

MonoBehaviours themselves aren’t heavy. It’s the magic methods like Update and things like coroutines that have an impact, and even then it depends on what’s happening inside of these. Checking a timer in Update will have far less of an impact than say calling GameObject.Find every frame.

Alright! Thank you both for your help, I’ll definitely check out those links and ideas. :slight_smile: