Create an ability system using Scriptable Objects

Note: I assume you already understand the concept of Scriptable Objects. In case you don’t, please go and take a look(Click Here).

Is pretty common these days to see games where you’re able to use certain “actions” on your characters every X seconds. This is normaly called as abilities which we can look on games such as RPGs, MOBAS, Strategy Games etc…

Today, let’s take a look on how to create an ability system using Scriptable Objects in Unity and it’s advantages.

Let’s create our base ability class

Example of character states

Now I’m gonna explain a little bit what is this class up to.

First, we have our cooldown and casting time fields. We can define wheter our ability has cooldown or not.

Casting Time, in case you don’t know, the casting time is the amount of seconds the ability has to wait to trigger it’s behavior.

Then, we have another IMPORTANT field which is the AllowedCharacterStates. As it’s name indicates, we use this as a limiter on this ability which is only going to be triggered if the owner of the ability is in some allowed state.

Then we have our Activate method where all the magic happens.

The Character Class

We’re not gonna get too deep on this class, let’s just create something simple that will allow us to test our ability system.

But why? 🤔… well, every single ability should have an Owner, this can be a simple GameObject reference, but I prefer to use a custom class to handle that. Also, it’s gonna be important due to our “Allowed States” field in the ability.

For this moment, let’s just leave this class as the “States handler” of each entity in our game.

Creating the Ability Holder Class

An ability holder is the in-game representation of an Ability. Is the class that will trigger abilities in the way we prefer.

Let’s first define the class fields.

And then, let’s create the states enum.

Now, we must add the method in charge to trigger the actual ability. This method can be called from other classes like the Player’s input to trigger ana bility once certain key is pressed…. let’s define a public method called TriggerAbility.

Note: You should add System.Linq on top of your script.

At this point we’re nerly finishing our system, but right now, this will throw us an error in the compiler. We’re missing two things: First, our HandleAbilityUsage coroutine and the cooldown coroutine.

Let’s add it.

Ok, now our ability system is completed. Let’s try it by creating a Test Ability.

First, create an object on an empty scene and the character component we just created and the Ability Holder.

It should look like this.

But…

You may notice that the Ability field is empty and says “None (Base Ability)”, well, this is because we haven’t set up any ability… let’s create one.

Just for testing purpose let’s create a Jump Ability class which derives from BASE ABILITY.

WAIT! We’re missing something important!

Before adding some behavior inside the Activate method, let’s not forget about something. Remember, we’re creating an scriptable object wihch is an ASSET, we should add the CreateAsset attribute to this class to be able to add it inside the ability holder.

Now, let’s add the actual jump behavior.

PERFECT!

In this way, we’ve just created our first ability using our system. Let’s get back to unity and create it.

Right click on the project window -> Create -> Abilities -> Jump.

This will create us an scriptable object to modify.

Project view.
Inspector View.

BACK TO OUR ABILITY HOLDER

Let’s add the jump ability we’ve just created.

NOW, I want you to do two things:

First, add a rigidbody to this character.

Secondly, add a rigidbody and box collider.

Now, from other script, call the TriggerAbility method from this AbilityHolder. Let’s create a player controller script and attach it to the object.

Let’s get back to the inspector

Press play and press the jump key, you’ll se your character is jumping. 😉

And this is it!

Using scriptable objects for abilities will give us an easy workflow everytime we want to add/edit their profiles.And it’s easy to extend in case you want to create an editor tool so designers can play with the system freely.

--

--