Need Help - Skill Tree System

Looking for feedback on how i would create a skill system like eve. Example sets of code would be great. Please advise accordingly. The values i am looking for are

3 Levels to each skill type (energy, weapons, etc)
3 tiers to each skill type (basic, moderate, advanced)
Level 1 in each skill tier unlocks a new ability (Prefab).
Click on the skill in gui and hit “research”.
Each skill takes time.

Research times
15 minutes, 2 hours , 4 hours (Tier 1)
8 hours, 16 hours, 32 hours (Tier 2)
3 days, 5 days, 7 days (Tier 3)

I dont know Js, so please give an idea/example in js. Highly appreciative of c# code examples.
if you can give an example of each condition above (levels, tiers, ties, unlock) i can manage from there.

No one’s going to write an entire script for you. What aspects are you struggling with in your own code?

2 Likes

Show the code you have currently and you may get some help. Seems like you’re asking for someone to write the entire script (s) for you…

Created a simple example PassiveTree and PassiveNode classes for you to look at. It doesn’t involve the timing part you will need CoRoutines for that most likely, but I hope this can help you get started. When you get more efficient you can replace some of the Lists and read from files instead, but this will get you started in understanding how it’s working.

PassiveNode.cs

//*************************
// Passive Node
//
// An individual node on the passive tree containing a description and various bonuses
//*************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PassiveNode
{

    public enum BonusType
    {
        percentPhysDmg,percentMagic,percentHealth,
        flatPhysDmg,flatMagic,flatHealth

    };

    //The name and description of this individual passive node
    public string bonusName;
    public string bonusDescript;
    public int bonusLevel = 1;

    //Each passive node may have multiple bonuses
    public List<BonusType> bonusTypes = new List<BonusType>();
    public List<float> bonusValues = new List<float>();
    public List<float> bonusValuePerLevel = new List<float>();

    //Add a new bonus to this individual passive node
    public void addBonus( BonusType type, float value, float valuePerLevel )
    {

        bonusTypes.Add(type);
        bonusValues.Add(value);
        bonusValuePerLevel.Add(valuePerLevel);

    }

    //Simulate one level up of the passive node
    public void levelUp()
    {
        //Level up each one of the bonuses in the passive node
        for(int i=0; i< bonusValues.Count; i++)
            bonusValues[i] += bonusValuePerLevel[i];

        //Add one to level count
        bonusLevel++;

    }
}

PassiveTree.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PassiveTree
{

    //List containing all passive bonuses
    List<PassiveNode> PassiveNodes = new List<PassiveNode>();


    //Total bonuses precalculated for battle in the calcBonuses function
    float calcPhysDmg, calcMagic, calcHealth;
    float calcPhysDmgPerc, calcMagicPerc, calcHealthPerc;


    //Use when adding a passive node for the first time (level 1)
    public void addPassiveNode( string passiveName )
    {

        switch( passiveName)
        {
            case "Brute":
            {
                    PassiveNode statNew = new PassiveNode();

                    //Describe the Brute passive bonus
                    statNew.bonusName = "Brute";
                    statNew.bonusDescript = "Add 5 physical damage and +10% on top of all damage. Each level up adds 2 physical damage and 3% physical damage";
                    statNew.bonusLevel = 1;

                    //Add both the bonuses to brute
                    statNew.addBonus(PassiveNode.BonusType.flatPhysDmg, 5.0f, 2.0f);
                    statNew.addBonus(PassiveNode.BonusType.percentPhysDmg, 0.10f, .03f);

                    //Add the newly created stat to the current passive tree
                    PassiveNodes.Add(statNew);

                    break;
            }
            case "Wizard":
            {
                    PassiveNode statNew = new PassiveNode();

                    //Describe the Wizard passive bonus
                    statNew.bonusName = "Wizard";
                    statNew.bonusDescript = "Add 4 magic and +8% on top of all magic. Each level up adds 2 magic and 2% magic";
                    statNew.bonusLevel = 1;

                    //Add both the bonuses to Wizard
                    statNew.addBonus(PassiveNode.BonusType.flatMagic, 4.0f, 2.0f);
                    statNew.addBonus(PassiveNode.BonusType.percentPhysDmg, 0.08f, .02f);

                    //Add the newly created stat to the current passive tree
                    PassiveNodes.Add(statNew);

                    break;
            }
            case "Constitution":
                {
                    PassiveNode statNew = new PassiveNode();

                    //Describe the Wizard passive bonus
                    statNew.bonusName = "Constitution";
                    statNew.bonusDescript = "Add 8 health and +10% on top of all health. Each level up adds 3 health and 2% health";
                    statNew.bonusLevel = 1;

                    //Add both the bonuses to Wizard
                    statNew.addBonus(PassiveNode.BonusType.flatHealth, 8.0f, 3.0f);
                    statNew.addBonus(PassiveNode.BonusType.percentHealth, 0.10f, .02f);

                    //Add the newly created stat to the current passive tree
                    PassiveNodes.Add(statNew);

                    break;
                }
        }

        //Recalculate the overall passive tree bonuses each time a new passive stat is added
        calculateBonuses();

    }

    //Each time a passive stat is changed, all bonuses are recalculated and stored in this class
    //for easy retrieval from the combat class when using Active Skills
    public void calculateBonuses()
    {
        //Set all bonuses to zero for recalculation
        calcHealth = calcHealthPerc = calcMagic = calcMagicPerc = calcPhysDmg = calcPhysDmgPerc = 0f;

        //Look through each passive stat in the passive tree
        for(int i=0; i< PassiveNodes.Count; i++)
        {
            //Look for each bonus in the passive stats
            for(int j=0; j<PassiveNodes[i].bonusValues.Count; j++)
            {

                float newBonus = PassiveNodes[i].bonusValues[j];

                //Find out which type of bonus it is to determine which stat is being added
                switch (PassiveNodes[i].bonusTypes[j])
                {
                    case PassiveNode.BonusType.flatHealth:
                    {
                            calcHealth += newBonus;
                            break;
                    }
                    case PassiveNode.BonusType.percentHealth:
                    {
                            calcHealthPerc += newBonus;
                            break;
                    }
                    case PassiveNode.BonusType.flatMagic:
                    {
                            calcMagic += newBonus;
                            break;
                    }
                    case PassiveNode.BonusType.percentMagic:
                    {
                            calcMagicPerc += newBonus;
                            break;
                    }
                    case PassiveNode.BonusType.flatPhysDmg:
                    {
                            calcPhysDmg += newBonus;
                            break;
                    }
                    case PassiveNode.BonusType.percentPhysDmg:
                    {
                            calcPhysDmgPerc += newBonus;
                            break;
                    }
                }

            }



        }



    }


    //Call on to level up a passive node, probably will be replaced later as leveling up will take place from a GUI
    public void levelupNode(PassiveNode node)
    {

        node.levelUp();
        calculateBonuses();

    }

}

As for adding more tiers or classifications that’s really easiest to do using enumerations, look at my example of enumerations in the passiveNode class, basically allows to create any sort of abstract classifications of objects, events, or ideas and treat them as a variable/number.

1 Like