You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity+Zenject跨场景代码与数据共享问题求助

解决Unity+Zenject跨场景共享单例数据的问题

当以Additive模式加载第二个场景时,虽然在主场景的MainInstaller中绑定了GameData为单例,但第二个场景注入的GameData是全新实例,修改后的数据无法共享。

原因分析

每个通过Unity原生SceneManager加载的场景,Zenject会自动创建独立的Scene Context和对应的容器。主场景的MainInstaller绑定的单例仅存在于主场景的容器中,第二个场景的容器无法访问这个实例,因此会重新创建GameData对象。


解决方案

方案1:使用全局Project Context(推荐)

全局Project Context的容器是所有场景共享的,适合存放跨场景的全局数据:

  1. 创建全局安装器:
public class ProjectInstaller : Installer<ProjectInstaller>
{
    public override void InstallBindings()
    {
        Container.Bind<GameData>().AsSingle().NonLazy();
    }
}
  1. 在Unity中创建Project Context:

    • 右键场景空白处 → Zenject → Project Context
    • 选中创建的ProjectContext对象,将ProjectInstaller拖到Installers列表中
  2. 移除MainInstaller中关于GameData的绑定代码,全局容器已处理单例绑定。

所有场景注入的GameData都会是同一个全局实例,数据修改会跨场景同步。

方案2:使用Zenject的SceneLoader复用主场景容器

如果需要保留场景级容器独立性,但共享特定实例,可用Zenject自带的SceneLoader代替Unity原生SceneManager,让加载的场景复用主场景容器:

修改主场景的注入代码:

private GameData _gameData;
private SceneLoader _sceneLoader;

[Inject]
public void Construct(GameData gameData, SceneLoader sceneLoader)
{
    _gameData = gameData;
    // 使用Zenject的SceneLoader加载场景
    _sceneLoader.LoadSceneAsync("Menu", LoadSceneMode.Additive);
}

private void Start()
{
    _gameData.CurrentState = GameStates.Menu;
}

这种方式下,第二个场景会使用主场景的容器,注入的GameData和主场景是同一个实例。


验证方法

在GameData的构造函数中添加日志,确认实例ID是否唯一:

public class GameData
{
    public GameData()
    {
        Debug.Log($"GameData实例创建,ID: {GetInstanceID()}");
    }

    public GameStates CurrentState { get; set; }
}

运行时若只输出一次日志,说明是单例;多次输出则存在多个实例。

内容的提问来源于stack exchange,提问作者Andrii Pavlov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 03:55:22