Unity+Zenject跨场景代码与数据共享问题求助
解决Unity+Zenject跨场景共享单例数据的问题
当以Additive模式加载第二个场景时,虽然在主场景的MainInstaller中绑定了GameData为单例,但第二个场景注入的GameData是全新实例,修改后的数据无法共享。
原因分析
每个通过Unity原生SceneManager加载的场景,Zenject会自动创建独立的Scene Context和对应的容器。主场景的MainInstaller绑定的单例仅存在于主场景的容器中,第二个场景的容器无法访问这个实例,因此会重新创建GameData对象。
解决方案
方案1:使用全局Project Context(推荐)
全局Project Context的容器是所有场景共享的,适合存放跨场景的全局数据:
- 创建全局安装器:
public class ProjectInstaller : Installer<ProjectInstaller> { public override void InstallBindings() { Container.Bind<GameData>().AsSingle().NonLazy(); } }
在Unity中创建Project Context:
- 右键场景空白处 →
Zenject→Project Context - 选中创建的
ProjectContext对象,将ProjectInstaller拖到Installers列表中
- 右键场景空白处 →
移除
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
相关产品推荐
相关产品推荐

