Need help deciding on an ability system in Unity

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I'm making an RPG and got to the point where I want a player to be able to use abilities. I decided to use a command pattern to keep keybindings flexible and now I've arrived with the following dilemma:



Command is an abstract class with an abstract method called Execute(). Every ability has a command class (for example FireBallCommand). I have a PlayerInput class. All buttons and the abilities that belong to it are defined there:



public class PlayerInput : MonoBehaviour 

private Command buttonF;
private Command buttonQ;

private PlayableCharacter character;

void Awake ()
character = GetComponent<PlayableCharacter>();
Initialize();


void Initialize()

//Setup controls here
//TODO: Get user's saved controls from db

//Temporarily hardcoded
buttonF = new BasicAttackCommand();
buttonQ = new FireBallCommand();


void Update ()
if (Input.GetKeyDown(KeyCode.F))

buttonF.Execute(character);

if (Input.GetKeyDown(KeyCode.Q))

buttonQ.Execute(character);





The FireBallCommand class looks like this, (atm it creates a GameObject because Command does not derive from MonoBehaviour because I read you should/cant create object using 'new' with MonoBehaviours, in code):



public class FireBallCommand : Command 

public override void Execute(PlayableCharacter character)

GameObject go = new GameObject();
go.AddComponent<FireBall>();
go.name = go.GetComponent<FireBall>().Name;
go.GetComponent<FireBall>().Execute(character);




Next, the abstract class Ability contains an abstract method Execute() as well. It also contains some properties such as name and cooldown. The actually ability derives from Ability and actually executes the ability:



public class FireBall: Ability 

PlayableCharacter character;

public override void Execute(Character character)

this.character = character as PlayableCharacter;
StartCoroutine(Fire());


IEnumerator Fire()

//Here it fires the fireball but there's no need to post that here.




This is the first time I am making a system like this. The dilemma is that I am not sure whether this is a right way to do it. It feels like casting one ability or spell is passing way to many classes and taking too much code in general. I thought of creating an AbilityManager that is always in the scene, which could be called to cast any spell/ability and takes a player as parameters.



In short: Do you think this would be a fine and fairly clean way to create an ability system? What other way(s) do you suggest? What could I change/remove/add to improve it?



P.S if anyone feels like answering this. I'm not sure where and how to implement cooldowns for the abilities in this system. Got an idea? :)



Thanks a lot in advance guys, if there's anything I should provide please let me know.










share|improve this question























  • Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
    – Philipp
    12 mins ago

















up vote
3
down vote

favorite












I'm making an RPG and got to the point where I want a player to be able to use abilities. I decided to use a command pattern to keep keybindings flexible and now I've arrived with the following dilemma:



Command is an abstract class with an abstract method called Execute(). Every ability has a command class (for example FireBallCommand). I have a PlayerInput class. All buttons and the abilities that belong to it are defined there:



public class PlayerInput : MonoBehaviour 

private Command buttonF;
private Command buttonQ;

private PlayableCharacter character;

void Awake ()
character = GetComponent<PlayableCharacter>();
Initialize();


void Initialize()

//Setup controls here
//TODO: Get user's saved controls from db

//Temporarily hardcoded
buttonF = new BasicAttackCommand();
buttonQ = new FireBallCommand();


void Update ()
if (Input.GetKeyDown(KeyCode.F))

buttonF.Execute(character);

if (Input.GetKeyDown(KeyCode.Q))

buttonQ.Execute(character);





The FireBallCommand class looks like this, (atm it creates a GameObject because Command does not derive from MonoBehaviour because I read you should/cant create object using 'new' with MonoBehaviours, in code):



public class FireBallCommand : Command 

public override void Execute(PlayableCharacter character)

GameObject go = new GameObject();
go.AddComponent<FireBall>();
go.name = go.GetComponent<FireBall>().Name;
go.GetComponent<FireBall>().Execute(character);




Next, the abstract class Ability contains an abstract method Execute() as well. It also contains some properties such as name and cooldown. The actually ability derives from Ability and actually executes the ability:



public class FireBall: Ability 

PlayableCharacter character;

public override void Execute(Character character)

this.character = character as PlayableCharacter;
StartCoroutine(Fire());


IEnumerator Fire()

//Here it fires the fireball but there's no need to post that here.




This is the first time I am making a system like this. The dilemma is that I am not sure whether this is a right way to do it. It feels like casting one ability or spell is passing way to many classes and taking too much code in general. I thought of creating an AbilityManager that is always in the scene, which could be called to cast any spell/ability and takes a player as parameters.



In short: Do you think this would be a fine and fairly clean way to create an ability system? What other way(s) do you suggest? What could I change/remove/add to improve it?



P.S if anyone feels like answering this. I'm not sure where and how to implement cooldowns for the abilities in this system. Got an idea? :)



Thanks a lot in advance guys, if there's anything I should provide please let me know.










share|improve this question























  • Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
    – Philipp
    12 mins ago













up vote
3
down vote

favorite









up vote
3
down vote

favorite











I'm making an RPG and got to the point where I want a player to be able to use abilities. I decided to use a command pattern to keep keybindings flexible and now I've arrived with the following dilemma:



Command is an abstract class with an abstract method called Execute(). Every ability has a command class (for example FireBallCommand). I have a PlayerInput class. All buttons and the abilities that belong to it are defined there:



public class PlayerInput : MonoBehaviour 

private Command buttonF;
private Command buttonQ;

private PlayableCharacter character;

void Awake ()
character = GetComponent<PlayableCharacter>();
Initialize();


void Initialize()

//Setup controls here
//TODO: Get user's saved controls from db

//Temporarily hardcoded
buttonF = new BasicAttackCommand();
buttonQ = new FireBallCommand();


void Update ()
if (Input.GetKeyDown(KeyCode.F))

buttonF.Execute(character);

if (Input.GetKeyDown(KeyCode.Q))

buttonQ.Execute(character);





The FireBallCommand class looks like this, (atm it creates a GameObject because Command does not derive from MonoBehaviour because I read you should/cant create object using 'new' with MonoBehaviours, in code):



public class FireBallCommand : Command 

public override void Execute(PlayableCharacter character)

GameObject go = new GameObject();
go.AddComponent<FireBall>();
go.name = go.GetComponent<FireBall>().Name;
go.GetComponent<FireBall>().Execute(character);




Next, the abstract class Ability contains an abstract method Execute() as well. It also contains some properties such as name and cooldown. The actually ability derives from Ability and actually executes the ability:



public class FireBall: Ability 

PlayableCharacter character;

public override void Execute(Character character)

this.character = character as PlayableCharacter;
StartCoroutine(Fire());


IEnumerator Fire()

//Here it fires the fireball but there's no need to post that here.




This is the first time I am making a system like this. The dilemma is that I am not sure whether this is a right way to do it. It feels like casting one ability or spell is passing way to many classes and taking too much code in general. I thought of creating an AbilityManager that is always in the scene, which could be called to cast any spell/ability and takes a player as parameters.



In short: Do you think this would be a fine and fairly clean way to create an ability system? What other way(s) do you suggest? What could I change/remove/add to improve it?



P.S if anyone feels like answering this. I'm not sure where and how to implement cooldowns for the abilities in this system. Got an idea? :)



Thanks a lot in advance guys, if there's anything I should provide please let me know.










share|improve this question















I'm making an RPG and got to the point where I want a player to be able to use abilities. I decided to use a command pattern to keep keybindings flexible and now I've arrived with the following dilemma:



Command is an abstract class with an abstract method called Execute(). Every ability has a command class (for example FireBallCommand). I have a PlayerInput class. All buttons and the abilities that belong to it are defined there:



public class PlayerInput : MonoBehaviour 

private Command buttonF;
private Command buttonQ;

private PlayableCharacter character;

void Awake ()
character = GetComponent<PlayableCharacter>();
Initialize();


void Initialize()

//Setup controls here
//TODO: Get user's saved controls from db

//Temporarily hardcoded
buttonF = new BasicAttackCommand();
buttonQ = new FireBallCommand();


void Update ()
if (Input.GetKeyDown(KeyCode.F))

buttonF.Execute(character);

if (Input.GetKeyDown(KeyCode.Q))

buttonQ.Execute(character);





The FireBallCommand class looks like this, (atm it creates a GameObject because Command does not derive from MonoBehaviour because I read you should/cant create object using 'new' with MonoBehaviours, in code):



public class FireBallCommand : Command 

public override void Execute(PlayableCharacter character)

GameObject go = new GameObject();
go.AddComponent<FireBall>();
go.name = go.GetComponent<FireBall>().Name;
go.GetComponent<FireBall>().Execute(character);




Next, the abstract class Ability contains an abstract method Execute() as well. It also contains some properties such as name and cooldown. The actually ability derives from Ability and actually executes the ability:



public class FireBall: Ability 

PlayableCharacter character;

public override void Execute(Character character)

this.character = character as PlayableCharacter;
StartCoroutine(Fire());


IEnumerator Fire()

//Here it fires the fireball but there's no need to post that here.




This is the first time I am making a system like this. The dilemma is that I am not sure whether this is a right way to do it. It feels like casting one ability or spell is passing way to many classes and taking too much code in general. I thought of creating an AbilityManager that is always in the scene, which could be called to cast any spell/ability and takes a player as parameters.



In short: Do you think this would be a fine and fairly clean way to create an ability system? What other way(s) do you suggest? What could I change/remove/add to improve it?



P.S if anyone feels like answering this. I'm not sure where and how to implement cooldowns for the abilities in this system. Got an idea? :)



Thanks a lot in advance guys, if there's anything I should provide please let me know.







unity c# architecture rpg combat






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago

























asked 3 hours ago









Niels van Dam

355




355











  • Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
    – Philipp
    12 mins ago

















  • Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
    – Philipp
    12 mins ago
















Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
– Philipp
12 mins ago





Please note that there are countless different ways to approach this problem in Unity. So there won't be a canonical answer to this question. The answers to this question will only provide you with inspirations. You have to decide which approach is the right one for your particular game.
– Philipp
12 mins ago











1 Answer
1






active

oldest

votes

















up vote
2
down vote













A very "unity" solution which I am using in one of my project would be to use prefabs to represent abilities. When the PlayerCharacter class uses an ability, it does nothing but instantiate a prefab which was previously assigned through the inspector. The prefab is then responsible for doing everything else about the ability. The prefab either is a fireball projectile with Renderer, ParticleSystem, Rigidbody, Collider, scripts, etc., or it is just an invisible game object which just does its job and then immediately destroys itself.



To implement cooldowns you could create a class like this:



[System.Serializable]
public class AbilitySlot
public GameObject abilityPrefab;
public float cooldownTime;
[HideInInspector] public float cooldownTimeLeft;
public int manaCost;
public KeyCode hotkey;




and then have a public AbilitySlot abilitySlots in your player class to keep track of all the abilities available to the player. You should then be able to edit this array in the inspector to assign the ability prefabs, set the cooldown time, the mana cost and assign a hotkey.



When the MonoBehaviour which handles the movement and damage mechanics of your fireball is also sufficiently data-driven, then this architecture should allow you to add a new ability without writing a single line of code.






share|improve this answer






















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "53"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgamedev.stackexchange.com%2fquestions%2f164301%2fneed-help-deciding-on-an-ability-system-in-unity%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote













    A very "unity" solution which I am using in one of my project would be to use prefabs to represent abilities. When the PlayerCharacter class uses an ability, it does nothing but instantiate a prefab which was previously assigned through the inspector. The prefab is then responsible for doing everything else about the ability. The prefab either is a fireball projectile with Renderer, ParticleSystem, Rigidbody, Collider, scripts, etc., or it is just an invisible game object which just does its job and then immediately destroys itself.



    To implement cooldowns you could create a class like this:



    [System.Serializable]
    public class AbilitySlot
    public GameObject abilityPrefab;
    public float cooldownTime;
    [HideInInspector] public float cooldownTimeLeft;
    public int manaCost;
    public KeyCode hotkey;




    and then have a public AbilitySlot abilitySlots in your player class to keep track of all the abilities available to the player. You should then be able to edit this array in the inspector to assign the ability prefabs, set the cooldown time, the mana cost and assign a hotkey.



    When the MonoBehaviour which handles the movement and damage mechanics of your fireball is also sufficiently data-driven, then this architecture should allow you to add a new ability without writing a single line of code.






    share|improve this answer


























      up vote
      2
      down vote













      A very "unity" solution which I am using in one of my project would be to use prefabs to represent abilities. When the PlayerCharacter class uses an ability, it does nothing but instantiate a prefab which was previously assigned through the inspector. The prefab is then responsible for doing everything else about the ability. The prefab either is a fireball projectile with Renderer, ParticleSystem, Rigidbody, Collider, scripts, etc., or it is just an invisible game object which just does its job and then immediately destroys itself.



      To implement cooldowns you could create a class like this:



      [System.Serializable]
      public class AbilitySlot
      public GameObject abilityPrefab;
      public float cooldownTime;
      [HideInInspector] public float cooldownTimeLeft;
      public int manaCost;
      public KeyCode hotkey;




      and then have a public AbilitySlot abilitySlots in your player class to keep track of all the abilities available to the player. You should then be able to edit this array in the inspector to assign the ability prefabs, set the cooldown time, the mana cost and assign a hotkey.



      When the MonoBehaviour which handles the movement and damage mechanics of your fireball is also sufficiently data-driven, then this architecture should allow you to add a new ability without writing a single line of code.






      share|improve this answer
























        up vote
        2
        down vote










        up vote
        2
        down vote









        A very "unity" solution which I am using in one of my project would be to use prefabs to represent abilities. When the PlayerCharacter class uses an ability, it does nothing but instantiate a prefab which was previously assigned through the inspector. The prefab is then responsible for doing everything else about the ability. The prefab either is a fireball projectile with Renderer, ParticleSystem, Rigidbody, Collider, scripts, etc., or it is just an invisible game object which just does its job and then immediately destroys itself.



        To implement cooldowns you could create a class like this:



        [System.Serializable]
        public class AbilitySlot
        public GameObject abilityPrefab;
        public float cooldownTime;
        [HideInInspector] public float cooldownTimeLeft;
        public int manaCost;
        public KeyCode hotkey;




        and then have a public AbilitySlot abilitySlots in your player class to keep track of all the abilities available to the player. You should then be able to edit this array in the inspector to assign the ability prefabs, set the cooldown time, the mana cost and assign a hotkey.



        When the MonoBehaviour which handles the movement and damage mechanics of your fireball is also sufficiently data-driven, then this architecture should allow you to add a new ability without writing a single line of code.






        share|improve this answer














        A very "unity" solution which I am using in one of my project would be to use prefabs to represent abilities. When the PlayerCharacter class uses an ability, it does nothing but instantiate a prefab which was previously assigned through the inspector. The prefab is then responsible for doing everything else about the ability. The prefab either is a fireball projectile with Renderer, ParticleSystem, Rigidbody, Collider, scripts, etc., or it is just an invisible game object which just does its job and then immediately destroys itself.



        To implement cooldowns you could create a class like this:



        [System.Serializable]
        public class AbilitySlot
        public GameObject abilityPrefab;
        public float cooldownTime;
        [HideInInspector] public float cooldownTimeLeft;
        public int manaCost;
        public KeyCode hotkey;




        and then have a public AbilitySlot abilitySlots in your player class to keep track of all the abilities available to the player. You should then be able to edit this array in the inspector to assign the ability prefabs, set the cooldown time, the mana cost and assign a hotkey.



        When the MonoBehaviour which handles the movement and damage mechanics of your fireball is also sufficiently data-driven, then this architecture should allow you to add a new ability without writing a single line of code.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 17 mins ago

























        answered 1 hour ago









        Philipp

        73.6k19169222




        73.6k19169222



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fgamedev.stackexchange.com%2fquestions%2f164301%2fneed-help-deciding-on-an-ability-system-in-unity%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke