はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】UnityでStrategyパターンを学んでみる

はじめに

今回はStarategyパターンを使って簡単なサンプルを作ってみる記事になります!

StarategyパターンをWikipedia先生で検索してみると、

Strategy パターンは、コンピュータープログラミングの領域において、アルゴリズムを実行時に選択することができるデザインパターンである。

Strategy パターン - Wikipedia

と書かれていました。

ざっくりとしたイメージはアルゴリズム毎にクラスを作成し、クラス内に詳細の処理を隠蔽し、クラスやインターフェイスのポリモーフィズムを用いて利用することです。(どうやらデリゲートを使う方法もあるみたい)

例えばカードゲームに例えると、カード毎にスキルがたくさんありますよね。そのスキル毎にクラスを作るみたいな感じです。

もしポリモーフィズムがいまいちの方は、かなり雑ではありますがこの記事でどういうものか少し分かるかもです。
www.hanachiru-blog.com

www.hanachiru-blog.com

メリット

分かりやすいメリットはif/switch文から解放されることです。
if/switch文はやはり長くなると見づらくなる傾向があるので、なくせるならなくした方がいいでしょう。

また新しいアルゴリズムを簡単に導入できる点もあります。
前回のようにカードゲームを考えると、新しいスキルを導入することが後から決まったときも、新しいクラスを作成しインターフェイスの指示を満たすように作成するだけで完成です。

さらに上と似ていますが、アルゴリズムの変更にも強いというのもあるでしょう。

私が思いつく限りはこのようなメリットが考えられます。

実際に使ってみる

いろんなものに応用できるように、なるべくシンプルに気を付けてスクリプトを作ってみました。

基本はこちらの記事を参考にさせていただいていますが、いくつか自分なりに書き換えてみてます。

github.com

using UnityEngine;

/// <summary>
/// アルゴリズムを実装するクラスの基底クラス
/// </summary>
abstract class Strategy
{
    public abstract void AlgorithmInterface();
}

/// <summary>
/// アルゴリズムAを実装しているクラス
/// </summary>
class ConcreteStrategyA : Strategy
{
    public override void AlgorithmInterface()
    {
        Debug.Log("アルゴリズムA");
    }
}

/// <summary>
/// アルゴリズムBを実装しているクラス
/// </summary>
class ConcreteStrategyB : Strategy
{
    public override void AlgorithmInterface()
    {
        Debug.Log("アルゴリズムB");
    }
}

/// <summary>
/// アルゴリズムCを実装しているクラス
/// </summary>
class ConcreteStrategyC : Strategy
{
    public override void AlgorithmInterface()
    {
        Debug.Log("アルゴリズムC");
    }
}

/// <summary>
/// アルゴリズムの制御情報を持つクラス(状況に応じて異なる動作を行う)
/// ConcreteStrategy を指定して作成し、Strategyオブジェクトへの参照を保持する
/// </summary>
class Context
{
    private Strategy _strategy;

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public Context(Strategy strategy)
    {
        this._strategy = strategy;
    }

    /// <summary>
    /// 実際に外部から使うメソッドはコレ
    /// </summary>
    public void ContextInterface()
    {
        _strategy.AlgorithmInterface();
    }
}

public class StrategyTest : MonoBehaviour
{
    private void Start()
    {
        Context context;

        context = new Context(new ConcreteStrategyA());
        context.ContextInterface();                     //アルゴリズムA

        context = new Context(new ConcreteStrategyB());
        context.ContextInterface();                     //アルゴリズムB

        context = new Context(new ConcreteStrategyC());
        context.ContextInterface();                     //アルゴリズムC
    }
}

f:id:hanaaaaaachiru:20190507194635p:plain

これを応用することで、モンスターにいろんな技を使わせている記事もありました。
techlife.supride.jp

さいごに

意外とUnityでのこういう記事が見つからなかったので、実際の利用例ではなくStarategyパターンの基本を紹介してみました。
色んなことに応用が利くので、覚えておいて損はないのかもしれません!

www.hanachiru-blog.com