土鍋で雑多煮

UnityでXR・ゲーム開発をしています。学んだことや備忘録、趣味の記録などを書いていきます。

MENU

【ECS&DI】Unity ECSでVContainerによるDIをやってみる

はじめに

どうも、土鍋です。

これは土鍋ひとり Advent Calendar 2024の1日目の記事です。

現在、ECSでゲームを作ってみているのですが、そのプロジェクトでDIって導入できないのかなーと思い調べたところ、VContainerが対応してくれているようなので、やってみました。

DefaultWorldにおけるDI

テスト用コード

DIで扱えるようにするにはSystemBase継承でSystemを構築する必要があります。
ISystemでは。現状できないようです。(そもそもMonoBehaviorから扱えないので)

public partial class SystemA : SystemBase
{
    protected override void OnUpdate() { }

    public void TestMessage()
    {
        Debug.Log("SystemA");
    }
}
public partial class SystemB : SystemBase
{
    [Inject]
    private SystemA _systemA;
    
    protected override void OnUpdate()
    {
        if (_systemA == null) return;
        _systemA.TestMessage();
    }
}

通常時のDIと同様に[Inject]のAttributeをつけるだけでそこに流し込まれます。

LifetimeScope

LifetimeScopeもMonoBehaviorのときと同様、以下のように簡単に記述できます。

このLifetimeScopeはECS管理ではなくMonoBehaviorのGameObjectにアタッチしてください。

public class TestLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        builder.RegisterSystemFromDefaultWorld<SystemA>();
        builder.RegisterSystemFromDefaultWorld<SystemB>();
    }
}

上記は以下のように書き換えることができます。

builder.UseDefaultWorld(systems =>
{
    systems.Add<SystemA>();
    systems.Add<SystemB>();
});

CustomWorldにおけるDI

自分で作ったWorldに関してDIを行うこともできます。

これによってWorld自体もVContainerに管理させることができるようです。

テスト用コード

public partial class SystemC : SystemBase
{
    readonly ServiceA serviceA;
    
    public SystemC(ServiceA serviceA)
    {
        this.serviceA = serviceA;
    }
    
    protected override void OnUpdate()
    {
        serviceA.TestMessage();
    }
}
public class ServiceA
{
    public void TestMessage()
    {
        Debug.Log("ServiceA");
    }
}

このような通常のクラスをSystemに流すように扱うことももちろんできる。

LifetimeScope

以下のように記述することで、Worldの生成から登録まで行っています。

builder.RegisterNewWorld("MyWorld", Lifetime.Scoped);
        
builder.RegisterSystemIntoWorld<SystemC>("MyWorld");
        
builder.Register<ServiceA>(Lifetime.Singleton);

参考

vcontainer.hadashikick.jp

hadashia.hatenablog.com