技術資料: VContainerを使用した依存性注入によるコンポーネント管理

1. 概要

この資料では、UnityにおいてVContainerを使用して依存性注入を実現し、IGameManagerインターフェースを使用して複数の実装クラスを切り替える方法を解説します。これにより、柔軟なゲームオブジェクトの管理やテストの容易化を実現します。


2. サンプルコードの説明

以下は、本資料で扱うコードの全体像です。

using UnityEngine;
using VContainer;

public class CheckHp : MonoBehaviour
{
    [Inject] IGameManager gameManager; // 依存性注入
    void Start()
    {
        Debug.Log($"注入されたGameManagerのHpは: {gameManager.Hp}です");
    }
}
using VContainer;
using VContainer.Unity;

public class GameLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        builder.Register<IGameManager, GameManagerMuteki>(Lifetime.Singleton);
        //builder.Register<IGameManager, GameManager>(Lifetime.Singleton);
        builder.RegisterComponentInHierarchy<CheckHp>();
    }
}
public interface IGameManager
{
    int Hp { get; set; }
}

public class GameManager : IGameManager
{
    public int Hp { get; set; } = 0; // 通常のHP
}

public class GameManagerMuteki : IGameManager
{
    public int Hp { get; set; } = 100000; // 無敵モードのHP
}

3. 各コンポーネントの役割

  1. IGameManager インターフェース
    • ゲーム管理用の共通インターフェース。
    • 実装クラスを切り替えて異なる挙動を持たせる際に使用。
  2. GameManager クラス
    • 標準的なゲームマネージャ。
    • HPの初期値が 0 に設定されています。
  3. GameManagerMuteki クラス
    • 無敵モード用のゲームマネージャ。
    • HPの初期値が 100000 に設定されています。
  4. CheckHp コンポーネント
    • 依存性注入を通じて IGameManager を取得し、Hp を確認するクラス。
  5. GameLifetimeScope クラス
    • VContainerのLifetimeScopeを継承し、依存性注入の設定を行う。
    • 現在はGameManagerMutekiを登録しています。

4. 実行結果

  1. ゲームを開始すると、CheckHp コンポーネントの Start メソッドが実行されます。
  2. GameLifetimeScope で登録された GameManagerMuteki が注入されるため、以下のログが出力されます。
注入されたGameManagerのHpは: 100000です

5. 実装の手順

https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer
  1. VContainerのインストール
    • Unityのパッケージマネージャで以下のURLを追加します
    • https://github.com/hadashiA/VContainer.git?path=VContainer/Assets/VContainer
  2. インターフェースと実装の作成
    • IGameManager と、それを実装する GameManager および GameManagerMuteki を作成します。
  3. 依存性注入の設定
    • GameLifetimeScope を作成し、builder.Register<IGameManager, GameManagerMuteki>(Lifetime.Singleton); を記述します。
  4. MonoBehaviourに注入
    • CheckHp コンポーネントで [Inject] 属性を使用して IGameManager を注入します。

6. 応用例

実行コードから切り替え

  • 異なるゲームモードへの適用
    • ゲーム開始時に、選択されたモード(通常モード、無敵モードなど)に応じて登録クラスを切り替える。
  • テスト環境の切り替え
    • テスト時にモックを注入して振る舞いを確認可能。
protected override void Configure(IContainerBuilder builder)
{
    if (isMutekiMode)
    {
        builder.Register<IGameManager, GameManagerMuteki>(Lifetime.Singleton);
    }
    else
    {
        builder.Register<IGameManager, GameManager>(Lifetime.Singleton);
    }
}

列挙型を使ってインスペクターから選択することも

using VContainer;
using VContainer.Unity;

public class GameLifetimeScope : LifetimeScope
{
    public enum SelGameManager
    {
        Release,
        Debug,
    }

    public SelGameManager selGameManager = SelGameManager.Release;

    protected override void Configure(IContainerBuilder builder)
    {
        if (selGameManager == SelGameManager.Release)
        {
            builder.Register<IGameManager, GameManager>(Lifetime.Singleton);
        }
        else
        {
            builder.Register<IGameManager, GameManagerMuteki>(Lifetime.Singleton);
        }
        builder.RegisterComponentInHierarchy<CheckHp>();
    }
}

7. 注意点

  • 注入の対象は必ず登録する
    • 例えば、CheckHpRegisterComponentInHierarchyで登録しないと、エラーが発生します。
  • Singletonの管理
    • Singletonに指定した場合、ゲーム全体でインスタンスが1つしか存在しません。状態管理に注意が必要です。

8. おわりに

VContainerを活用することで、コードの保守性や拡張性が向上します。特に、ゲームの状態管理やモード切り替えが必要な場合、柔軟に対応できる設計が可能です。この資料を参考に、プロジェクトにVContainerを取り入れてみてください!

おまけ

デバッグモードの有効化

デバッグウィンドウの表示

実行中の様子