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

拆分场景后从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:15:34