VContainer-scoping/generate-child-via-scene | 作用域——通过场景或 prefab 生成子作用域

如何将附加场景设为子作用域

加载场景时如何设置父级

在加载场景前指定 LifetimeScope 对象即可建立父子关系。

class SceneLoader
{
    readonly LifetimeScope parent;

    public SceneLoader(LifetimeScope lifetimeScope)
    {
        parent = lifetimeScope; // 注入该类所属的 LifetimeScope
    }

    IEnumerator LoadSceneAsync()
    {
        // 在这个块中生成的 LifetimeScope 将以 `this.lifetimeScope` 为父对象
        using (LifetimeScope.EnqueueParent(parent))
        {
            // 若加载的场景包含 LifetimeScope,其父级将被设为当前 `parent`。
            var loading = SceneManager.LoadSceneAsync("...", LoadSceneMode.Additive);
            while (!loading.isDone)
            {
                yield return null;
            }
        }
    }

    // UniTask 示例
    async UniTask LoadSceneAsync()
    {
        using (LifetimeScope.EnqueueParent(parent))
        {
            await SceneManager.LoadSceneAsync("...", LoadSceneMode.Additive);
        }
    }
}

LifetimeScope 本质是 GameObject 游戏对象,也可以通过场景搜索获取:

var parent = LifetimeScope.Find<BaseLifetimeScope>();

如何为下一个场景添加额外注册

通常需要在加载场景时补充注册信息,

例如异步加载资源后完善上下文配置。

在这种情况下,可以使用以下方式:

// 在此代码块中生成的 LifetimeScope 将应用额外注册。
using (LifetimeScope.Enqueue(builder =>
{
    // 为即将加载的场景预先注册
    builder.RegisterInstance(extraInstance);
}))
{
    // 加载场景操作..
}
// 使用安装器类型注册
class FooInstaller : IInstaller
{
    public void Install(IContainerBuilder builder)
    {
        builder.Register<ExtraType>(Lifetime.Scoped);
    }
}

using (LifetimeScope.Enqueue(fooInstaller)
{
    // ... 加载场景
}
// 可同时使用 EnqueueParent() 和 Enqueue()。
using (LifetimeScope.EnqueueParent(parent))
using (LifetimeScope.Enqueue(builder => ...)
{
    // ... 加载场景
}

如何在 Inspector 中预设父级

LifetimeScope 可以通过指定父对象的类型进行序列化。

在基础场景中。

在附加场景中。

:::caution
当场景变为 "isLoaded" 状态时,如果在 Inspector 中设置的父类型未找到,将触发错误。
:::

posted @ 2025-02-18 01:28  凌雪寒  阅读(58)  评论(0)    收藏  举报