MRが楽しい

MRやVRについて学習したことを書き残す

VContainerのHelloWorldを試す その5(EnqueueParentを使ってシーンを跨いで親LifetimeScopeを設定する)

本日は VContainer の小ネタ枠です。
EnqueueParent を使ってシーンを跨いで親 LifetimeScope を設定する手順について記事に残します。

前回記事

以下の前回記事のプロジェクトを利用します。
bluebirdofoz.hatenablog.com

シーンを追加する

異なる LifetimeScope を持ったシーンを追加するサンプルを作成しました。

1つ目のシーン

・RootParentLifetimeScope.cs

using VContainer;
using VContainer.Unity;

namespace EnqueueParentSample
{
    public class RootParentLifetimeScope : LifetimeScope
    {
        protected override void Configure(IContainerBuilder builder)
        {
            // HelloWorldServiceをDIコンテナに登録する
            builder.Register<HelloWorldService>(Lifetime.Singleton);
        }
    }
}


2つ目のシーン

・GameLifetimeScope.cs

using UnityEngine;
using VContainer;
using VContainer.Unity;

namespace EnqueueParentSample
{
    public class GameLifetimeScope : LifetimeScope
    {
        [SerializeField]
        private HelloScreen helloScreen;

        protected override void Configure(IContainerBuilder builder)
        {
            // GamePresenterをVContainerのEntryPointに登録する
            builder.RegisterEntryPoint<GamePresenter>();
            // HelloScreenコンポーネントをDIコンテナに登録する
            builder.RegisterComponent<HelloScreen>(helloScreen);
        }
    }
}

GameLifetimeScope.cs は HelloWorldService を参照する必要があるので、RootParentLifetimeScope.cs の子 LifetimeScope である必要があります。

シーンの遷移処理

まずは以下の通り、普通にシーンを追加するのみの以下のスクリプトを作成しました。
1つ目のシーンが起動すると同時に LoadScene 関数が呼び出されて2つ目のシーンが追加される形で開きます。
・NextSceneLoader.cs

using UnityEngine;
using UnityEngine.SceneManagement;
using VContainer.Unity;

namespace EnqueueParentSample
{
    public class NextSceneLoader : MonoBehaviour
    {
        void Start()
        {
            SceneManager.LoadScene("NextEnqueueParentSample", LoadSceneMode.Additive);
        }
    }
}

合わせてシーン参照のため、BuildSettingsにシーンを登録しておきます。

動作確認

この状態でシーンを再生してみます。
すると LifetimeScope はシーン間では参照できないため、以下のエラーが発生します。

VContainerException: Failed to resolve EnqueueParentSample.GamePresenter : No such registration of type: EnqueueParentSample.HelloWorldService


EnqueueParentを使ってシーンを跨いで親LifetimeScopeを設定する

次にシーンを遷移するスクリプトを以下の通り、修正しました。
・NextSceneLoader.cs

using UnityEngine;
using UnityEngine.SceneManagement;
using VContainer.Unity;

namespace EnqueueParentSample
{
    public class NextSceneLoader : MonoBehaviour
    {
        [SerializeField]
        private LifetimeScope firstSceneLifetimeScope;

        void Start()
        {
            LifetimeScope.EnqueueParent(firstSceneLifetimeScope);
            SceneManager.LoadScene("NextEnqueueParentSample", LoadSceneMode.Additive);
        }
    }
}

firstSceneLifetimeScope 変数には1つ目のシーンの LifetimeScope の参照を設定します。

LifetimeScope.EnqueueParent は指定の LifetimeScope を親として登録する関数です。
このため、2つ目のシーンの LifetimeScope が1つ目の LifetimeScope で登録した HelloWorldService を参照できるようになります。
vcontainer.hadashikick.jp

動作確認

シーンを再生して確認してみます。
参照が正常に解決され、エラーが発生せずにスクリプトが正常に動作するようになりました。