🔗

VContainer入門 ~新入力システム編~

2022/06/20に公開

新Input SystemとVContainerを併用する

課題

新Input Systemのロジック部分をVContainerで切り離せるか.

Input Actionの設定

Toggleというアクションを追加する. Hキーを押すと内部状態を切り替えることができる.

VContainerの準備

まずGameLifetimeScopeという名前の空のオブジェクトを作る. 同名のスクリプトを作成し以下のように定義する.

GameLifetimeScope.cs
using UnityEngine.InputSystem;

using VContainer;
using VContainer.Unity;

public class GameLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
	builder.Register<ToggleLogic>(Lifetime.Singleton);
	builder.RegisterComponentInHierarchy<PlayerInput>();
        builder.RegisterEntryPoint<ToggleController>();
    }
}

コンテナ(実際にはコンテナのビルダ)にいくつかのクラスを登録する. RegisterComponentInHierarchyを使うと「まぁ, どっかにあるやろ」的なコンポーネントのインスタンスを取得することができる. 今回のPlayerInputにはちょうどよかった.

Toggleの機能を実装する

内部状態readyをHキーの入力に応じて切り替えるだけです. DebugLog以外は生のC#のコードになっている.

ToggleLogic.cs
using UnityEngine;

public class ToggleLogic
{
    bool ready = false;
    public void toggle() 
    {
        if (ready)
        {
            Debug.Log("OFF");
            this.ready = false;
        }
        else
        {
            Debug.Log("ON");
            this.ready = true;
        }
    }
}

コールバックの登録

コントローラークラスを用意する. ポイントはIStartableインターフェースを使うことである. こうすることでVContainer独自のPlayerLoopSystemのStart呼び出し時にデリゲートを登録できる. [1]

using UnityEngine;
using UnityEngine.InputSystem;

using VContainer.Unity;

public class ToggleController : IStartable
{
    readonly ToggleLogic toggleLogic;
    readonly PlayerInput playerInput;

    public ToggleController(ToggleLogic toggleLogic, PlayerInput playerInput)
    {
        this.toggleLogic = toggleLogic;
        this.playerInput = playerInput;
    }

    void IStartable.Start()
    {
        InputActionMap actionMap = this.playerInput.currentActionMap;
        InputAction toggleAction = actionMap["Toggle"];
        toggleAction.performed += context => this.toggleLogic.toggle();
    }
}

まとめ

ロジックだけを切り出して疎結合にすることができた. 次はモデルもちゃんと切り分けて使ってみたい.

Reference

  1. 【Unity】Input Systemの基本的な使い方
  2. VContainer Docs - Hello World
  3. Class InputAction
  4. Class InputActionMap
脚注
  1. デリゲートとメソッドの違いが良く分かっていない・・・ ↩︎

Discussion