Unityで使われているデザインパターンのサンプル

2024年4月17日

Unityでは、以下のようなデザインパターンがよく使われています。Markdown形式で説明します。

Singletonパターン

Singletonパターンは、クラスのインスタンスが1つしか存在しないことを保証するためのパターンです。Unityでは、マネージャーやシングルトンクラスの実装によく使用されます。以下は、Singletonパターンの例です。

public class SingletonExample : MonoBehaviour
{
    private static SingletonExample instance = null;

    public static SingletonExample Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<SingletonExample>();
            }
            return instance;
        }
    }

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(gameObject);
        }
    }

    public void DoSomething()
    {
        Debug.Log("SingletonExample.DoSomething called");
    }
}

この例では、SingletonExampleクラスがSingletonパターンで実装されています。instanceフィールドは、Singletonインスタンスを格納するための変数です。Instanceプロパティは、instanceフィールドを返すために使用されます。Awake()メソッドは、Singletonインスタンスを初期化するために使用されます。DoSomething()メソッドは、Singletonインスタンスで実行されるメソッドです。

Factoryパターン

Factoryパターンは、オブジェクトの生成をカプセル化するためのパターンです。Unityでは、プレハブやインスタンスの生成によく使用されます。以下は、Factoryパターンの例です。

public class MyObjectFactory : MonoBehaviour
{
    public GameObject objectPrefab;

    public GameObject CreateObject()
    {
        return Instantiate(objectPrefab);
    }
}

この例では、MyObjectFactoryクラスがFactoryパターンで実装されています。objectPrefabフィールドは、生成するオブジェクトのプレハブを格納するための変数です。CreateObject()メソッドは、objectPrefabを使用して、新しいオブジェクトを生成するために使用されます。

Observerパターン

Observerパターンは、オブジェクトの状態変化を監視するためのパターンです。Unityでは、イベントシステムやコールバックによく使用されます。以下は、Observerパターンの例です。

public class MySubject : MonoBehaviour
{
    public event Action<int> OnValueChanged;

    private int value;

    public int Value
    {
        get { return value; }
        set
        {
            this.value = value;
            OnValueChanged?.Invoke(value);
        }
    }
}

public class MyObserver : MonoBehaviour
{
    private void Start()
    {
        MySubject subject = FindObjectOfType<MySubject>();
        subject.OnValueChanged += OnValueChanged;
    }

    private void OnValueChanged(int value)
    {
        Debug.Log("MyObserver.OnValueChanged called with value: " + value);
    }
}

この例では、`MySubject`クラスがSubject、`MyObserver`クラスがObserverとして実装されています。`MySubject`クラスには、`OnValueChanged`イベントがあります。`MyObserver`クラスは、`OnValueChanged`イベントに登録されており、`OnValueChanged()`メソッドが呼び出されます。`OnValueChanged()`メソッドは、オブジェクトの状態変化を監視するために使用されます。

Strategyパターン

Strategyパターンは、アルゴリズムを交換可能にするためのパターンです。Unityでは、AIやゲームプレイの戦略によく使用されます。以下は、Strategyパターンの例です。

public interface IAttackStrategy
{
    void Attack();
}

public class BasicAttackStrategy : IAttackStrategy
{
    public void Attack()
    {
        Debug.Log("Basic attack");
    }
}

public class SpecialAttackStrategy : IAttackStrategy
{
    public void Attack()
    {
        Debug.Log("Special attack");
    }
}

public class Character : MonoBehaviour
{
    private IAttackStrategy attackStrategy;

    public void SetAttackStrategy(IAttackStrategy strategy)
    {
        attackStrategy = strategy;
    }

    public void Attack()
    {
        attackStrategy?.Attack();
    }
}

この例では、`IAttackStrategy`インターフェースがStrategy、`BasicAttackStrategy`クラスと`SpecialAttackStrategy`クラスがConcrete Strategy、`Character`クラスがContextとして実装されています。`IAttackStrategy`インターフェースには、`Attack()`メソッドがあります。`BasicAttackStrategy`クラスと`SpecialAttackStrategy`クラスは、`Attack()`メソッドを実装します。`Character`クラスには、`attackStrategy`フィールドと`SetAttackStrategy()`メソッドがあります。`Attack()`メソッドは、`attackStrategy`フィールドで指定された攻撃戦略を実行するために使用されます。 以上が、Unityでよく使用されるデザインパターンのいくつかの例です。これらのパターンを使用することで、より効率的で柔軟なコードを作成することができます。