(Unity) VContainer + MessagePipe を用いた動的に生成したGameObjectへのInject


ソース

// LifetimeScope で登録
public class GameLifetimeScope : LifetimeScope {
    protected override void Configure(IContainerBuilder builder) {

        var options = builder.RegisterMessagePipe();
        builder.RegisterMessageBroker<FlickEvent>(options);
        builder.RegisterMessageBroker<AttackData>(options);
    }
}
// Flickイベントを購読し、Prefabを生成するクラス
// 注 Hierarcy 上ですでにLifetimeScope で紐付いている
public class ObjectManager : MonoBehaviour {
    [SerializeField] private GameObject linePrefab;

    [Inject] private ISubscriber<FlickEvent> flickSub;

    [Inject] private IObjectResolver container;

    public ObjectManager(IObjectResolver container) {
        this.container = container;
    }

    void Start() {
        this.transform.position = Vector3.zero;

        flickSub.Subscribe(fev => DrawLine(fev)).AddTo(this);
    }

    void DrawLine(FlickEvent fev) {
        if (linePrefab == null) {
            throw new ArgumentNullException("ObjectManager needs linePrefab.");
        }

        var line = container.Instantiate(linePrefab, this.transform);

    }
}

// 生成されるPrefabが持つInjectを利用したいクラス
public class AttackObject : MonoBehaviour {

    [Inject] private IPublisher<AttackData> atackPub;

    // 触れた物体が敵の場合、攻撃を発生させる処理
    private void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag != "Enemy") return;

        atackPub.Publish(
            new AttackData(damage, other.gameObject)
        );

    }
}

参考

  1. 公式ドキュメント

補足

  • ファクトリーパターンでの実装もあるようです、余裕があればこちらもやってみたい

記事について

ソースに関しては、抜粋のためコピペでは動作しない可能性があります。
コメント、補足、LGTM大歓迎です。