Implementing the Strategy design pattern using Scriptable Objects in Unity
Tags: unity3d, csharp, gamedev
Published: 2019-04-28 20:52:07

---
title: Implementing the Strategy design pattern using Scriptable Objects in Unity
published: true
description: How to implement the classic GOF strategy pattern with the flexibility & power of Scriptable Objects
tags: #unity #csharp #gamedev
---

# Implementing the _Strategy_ design pattern using `ScriptableObject` in Unity

_Strategy_ is a design pattern from the book [Design Patterns (GOF)](https://en.wikipedia.org/wiki/Design_Patterns)
The purpose of the pattern is to enable changing behaviour at runtime in a clean way (not a bunch of if-statements).

You can read more about the _Strategy_ pattern [here](https://en.wikipedia.org/wiki/Strategy_pattern) as it will not be covered here.

Implementing the pattern in C# is pretty straight forward and can be explained as simple as this:

## C# example

Imagine you have a `Player` class that can perform different kinds of attacks. This could look something like this.

<pre>
<code>
    class Player
    {
        void Attack(AttackType type)
        {
            if(type == AttackType.Melee)
            {
                // TODO: melee logic
            }
            else if(type == AttackType.Crossbow)
            {
                // TODO: crossbow logic
            }
        }
    }
</code>
</pre>

Adding a new attack means adding a new if-statement. Not to mention this method will quickly get very long and hard to follow. Commonly, attacks will need different parameters. Both might need some kind of damage, but crossbow will need range and even possibly ammo, while melee won't. Of course we could pass all of those parameters to the `Attack` method. But strategy can make this a lot cleaner.

Instead, using _Strategy_ we can make this a bit cleaner:


<pre>
<code>
// Player.cs
class Player
{
    void Attack(IAttack attack)
    {
        attack.Execute(this);
    }
}

// IAttack.cs
interface IAttack
{
    void Execute(Player player);
}

// MeleeAttack.cs
class MeleeAttack : IAttack
{
    public int Damage { get; set; }

    void Execute(Player player)
    {
        // TODO: Melee attack logic
    }
}

// CrossbowAttack.cs
class CrossbowAttack : IAttack
{
    public int Damage { get; set; }
    public float Range { get; set; }
    public int Arrows { get; set; }

    void Execute(Player player)
    {
        // TODO: Crossbow attack logic
    }
}
</code>
</pre>

Alright, there's a little bit more code. We moved them into different files and separated each attacks' functionality into different classes all implementing `IAttack`. Now the player only needs to know about `IAttack` and passes itself as a parameter to the attack it is using.

Adding a new attack now is as simple as adding a new attack-class. No changes in the `Player`-class are needed.

## Unity example using `ScriptableObject`

So this is all nice and dandy. But what about doing this in Unity? I think there are benefits from doing this with just C# in Unity, but when it really shines is when using Unitys `ScriptableObject` for the implementations of each strategy.

[Read more about ScriptableObject](https://docs.unity3d.com/ScriptReference/ScriptableObject.html)

The benefit of `ScriptableObject` is that they can be created as assets. This means you can drag-drop your strategies in the Unity Editor directly to game objects. (This also comes with a cost, we'll get to that later)

<pre>
<code>
// Player.cs
class Player : MonoBehaviour
{
    public void Attack(IAttack attack)
    {
        attack.Execute(this);
    }
}

// IAttack.cs
interface IAttack
{
    void Execute(Player player);
}

// Attack.cs
public abstract class Attack : ScriptableObject, IAttack
{
    public abstract void Execute(Player player);
}

// MeleeAttack.cs
[CreateAssetMenu(menuName="Custom/Attacks/Melee Attack")]
class MeleeAttack : Attack
{
    public int Damage = 1;

    public override void Execute(Player player)
    {
        // TODO: Melee attack logic
    }
}

// CrossbowAttack.cs
[CreateAssetMenu(menuName="Custom/Attacks/Crossbow Attack")]
class CrossbowAttack : Attack
{
    public int Damage = 3;
    public float Range = 20f;
    public int Arrows = 5;

    public override void Execute(Player player)
    {
        // TODO: Crossbow attack logic
    }
}
</code>
</pre>

A couple of things are different here:

* We added an abstract class `Attack` that inherits `ScriptableObject` and implements `IAttack`
* `MeleeAttack` and `CrossbowAttack` inherit `Attack` instead of using the interface directly
* An attribute `CreateAssetMenu` was added - this makes it possible to right-click in the Unity Editor and add a new asset for that specific type of attack.
* The properties were changed to fields - meaning we can now also edit these values in the Unity Editor for our assets

This also means it is possible to create different assets for the same type of attack. For example we could have a weak melee attack and a strong one, and perhaps add a cost in stamina for using that attack.

The flexibility of this is pretty great. And the separation of the logic from the `Player` makes it even easier.

Another thing means that someone who isn't a programmer can easily add new configurations of attacks without touching the code!

### The drawbacks

Honestly this isn't a big deal but might save you some time: Remember that these `ScriptableObject`s are Assets. This means when you attach a `ScriptableObject` to a game object, it will use the same instance of that asset. Even if two different objects are using it.

That is why _State_ should **never** be stored in the `ScriptableObject`. Think of it as configuration and behaviour only.

Another thing is that you can't just instantiate a `ScriptableObject` on the fly, Unity doesn't allow it. However you can use this factory method:

<code>
ScriptableObject.CreateInstance<MeleeAttack>()
</code>

This will give you a new instance of a `ScriptableObject` that is **not** an asset.

*This is my first post here so, hello! :)*