Best way to create multiple characters with the same variables for stats, but different amounts and abilities.

In my game I intend on having multiple characters that will all have health, defence, attack etc. but each character will have different values for their health, defence, attack and so on. This is mostly fine, as this can mainly be sorted out on the prefab as I can change public variables and save it to that specific character.
_
In addition to the basic stats, each character will have fundamentally different abilities, with different effects, animations e.g. some characters will have ranged abilities, some will be melee attacks, some will just affect the beforementioned stats.
_
I want to know the most effective way to have the stats and abilities change depending on what character is selected.
_
I have a couple ideas on how to tackle having these multiple characters, but I’m not sure how resource intensive they may be, or just how unnecessarily complicated I’m making it.
_

  • Idea 1: My initial thought was just having a separate script for each character with only their specific stats and abilities, but this seems inefficient as I would have duplicate code for every character (but would get around the issue in idea 2)
    _
  • Idea 2: My next thought was to have just one massive script that would be used for every character. The idea here is that when the game starts, the character would be identified by a public variable and their abilities assigned by this same variable. Then, when an ability is used, the game checks what character is being played, and then play the ability corresponding to the same public variable from earlier. I’m not sure if this is inefficient or not as I’m not too sure how intensive it would be to check the character every time the ability is used or if there is a way around this.

_
I’m still very new to C# and programming in general so there’s likely a better way to the above. Any help is greatly appreciated.
_
Below is some code I’ve created for my second idea and it seems to work, but as I said it may not be the best way to do this as it uses the update function a lot, and will use it even more when there are multiple abilities per character.
_
public int maxHP;
public int AttackDMG;
public int defence;

    public string charClass;

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.E))
        {
            ChangeCharacterAbilities(charClass); //check what class is being used
        }
    }
    public void ChangeCharacterAbilities(string className)
    {
        switch (className)
        {
            case "Knight":
                KnightUtility(); //play ability is class == knight
                break;
            case "Ranger":
                RangerUtility();
                break;
        }
    }
    void KnightUtility()
    {
        print("Use Knight utility ability"); //ability for knight class
    }

    void RangerUtility()
    {
        print("Use Ranger utility ability");
    }

Hmm, you can do this in a single script. However this script would include some other C# classes (not unity monobehavior scripts, but simple classes).
Basically what you need is Inheritance and Interfaces
(read about them on c# docs - they are quite useful concepts available in a lot of programming languages)


You can design your classes somewhat like this (definitely not the only way):

GeneralDude class - contains methods to walk, run, eat, sleep, whatever common action every type of character can do - and which is the same for all types of characters.

ParticularActionsInterface class - contains “contract” methods (which are basically methods that are only declared - no body) that generally map the actions that you want to make different for each character type. Let’s say that each character should have 2 actions which are unique. You can have in that interface 2 methods: uniqueaction1() and uniqueaction2().

Next, you should create 1 class per each character type you wish to have. Every one of these classes will inherit the GeneralDude class and also the ParticularActionsInterface class. This will have the following effects:

  1. classes which inherit the GeneralDude class will now have the public methods from GeneralDude available and ready to be used.

  2. classes which inherit the ParticularActionsInterface class will force you to provide definitions for the methods in ParticularActionsInterface. Here you should provide unique behaviors for your actions, in the methods uniqueaction1() and uniqueaction2().


After that, you include the class files to your Unity script and create your global variables (one for each character type). When you assign one of the character types, the particular actions will change based on the interface methods definitions you wrote for each character type class.

Now your life is made easier because you will mostly call the same methods no matter what the current character type is (ie. both warriors and hunters can walk, run, or perform uniqueaction1 or uniqueaction2). Also neat is that for the most part, you won’t have duplicate code.