拆分场景后从Photon Fusion加载BattleScene时Zenject与StateMachine同步问题
解决方案
一、恢复Zenject跨场景绑定
- 核心绑定移至ProjectContext:将全局依赖(如StateMachine、核心服务)的绑定放在
ProjectContext的Installer中,ProjectContext是全局持久化的,不会随场景卸载销毁。将BattleScene的SceneContext设置为继承ProjectContext的绑定(Inspector中勾选"Inherit From Project Context"),避免创建独立容器导致绑定丢失。 - 手动处理动态场景加载的容器传递:如果通过Photon Fusion API加载BattleScene,在场景加载完成后手动关联容器:
// Photon场景加载完成回调 public void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name != "BattleScene") return; var sceneContext = scene.GetRootGameObjects() .First(go => go.TryGetComponent(out SceneContext _)) .GetComponent<SceneContext>(); sceneContext.Container = ProjectContext.Instance.Container; sceneContext.Install(); } - 避免重复初始化:检查BattleScene的
SceneContext的"Auto Install"选项,确保仅在场景加载完成后初始化一次,防止容器被重置。
二、同步StateMachine状态
- 全局持久化StateMachine实例:将StateMachine通过Zenject绑定为单例,确保场景切换时不被销毁:
// ProjectContext的Installer中 Container.Bind<IStateMachine>().To<GameStateMachine>().AsSingle(); - 显式恢复状态:加载BattleScene前记录当前状态及关键数据,加载完成后强制恢复:
// 加载前记录状态 var stateMachine = ProjectContext.Instance.Container.Resolve<IStateMachine>(); GameState prevState = stateMachine.CurrentState; PlayerStateData playerData = stateMachine.CurrentState.GetPlayerRuntimeData(); // 加载完成后恢复 stateMachine.SetState(prevState, forceEnter: true); stateMachine.CurrentState.RestorePlayerData(playerData); - 修复事件订阅:场景卸载时取消StateMachine的事件监听,BattleScene初始化后重新订阅,避免空引用或重复触发:
// 场景卸载时 stateMachine.OnStateChanged -= OnStateChanged; // BattleScene初始化后 stateMachine.OnStateChanged += OnStateChanged;
三、Photon Fusion与Zenject协同适配
- 绑定NetworkRunner到全局容器:在ProjectContext的Installer中绑定Photon的NetworkRunner为单例,确保BattleScene中的依赖可通过Zenject注入:
Container.Bind<NetworkRunner>().FromInstance(NetworkRunner.Singleton).AsSingle(); - 同步初始化时机:在Photon的
OnRoomJoined或OnSceneLoadDone回调中触发Zenject初始化逻辑,确保网络环境就绪后再恢复游戏状态,避免因网络未同步导致StateMachine流程混乱。
调试技巧
- 用
Debug.Log(ProjectContext.Instance.Container.HasBinding<IStateMachine>())检查全局绑定是否存在; - 在StateMachine的
EnterState和ExitState方法中添加日志,确认状态切换是否符合预期; - 检查BattleScene中注入对象是否为null,定位绑定失效的具体位置。
内容的提问来源于stack exchange,提问作者Phoenix
相关产品推荐
相关产品推荐

