项目地址:
在 MyFramework 里,GameScene 不是 Unity 的 .unity 场景。
GameScene 是逻辑场景,用来划分游戏的大阶段。
SceneProcedure 是逻辑场景内部的流程节点,用来划分同一个阶段内的界面和逻辑变化。
两者的核心区别不是名字,也不是层级,而是资源生命周期。
bash
GameScene:
不同 GameScene 之间通常不共享资源
从一个 GameScene 跳到另一个 GameScene 时,会卸载当前 GameScene 使用的资源
SceneProcedure:
同一个 GameScene 内部的流程节点
Procedure 之间通常只是逻辑或界面变化
切换 Procedure 时一般不会卸载资源
这就是 MyFramework 中划分 GameScene 和 SceneProcedure 的核心准则。
一、GameScene 按资源生命周期划分
一个 GameScene 表示一个大的游戏阶段。
不同 GameScene 之间通常资源差异很大。
例如:
bash
LoginScene
登录相关资源
登录 UI
服务器列表 UI
账号创建 UI
MainScene
大厅资源
世界地图资源
背包 UI
商城 UI
主界面 UI
BattleScene
战斗角色资源
战斗场景资源
技能特效
战斗 UI
结算 UI
这些阶段之间通常不会共享大量资源。
从 LoginScene 进入 MainScene 时,登录界面的资源就不需要继续保留。
从 MainScene 进入 BattleScene 时,大厅和世界地图相关资源也可能需要释放。
所以 GameScene 的切换,通常意味着:
bash
退出当前逻辑场景
清理当前场景逻辑
卸载当前场景占用的资源
进入新的逻辑场景
加载新场景需要的资源
启动新场景的流程
这就是 GameScene 的边界。
它不是为了表示某个界面打开了,也不是为了表示某个按钮状态变化了。
它表示一组资源和逻辑生命周期。
二、SceneProcedure 按流程和界面变化划分
SceneProcedure 是 GameScene 内部的流程节点。
同一个 GameScene 内部的不同 SceneProcedure,通常会频繁来回切换。
例如登录场景里可能有:
bash
LoginScene
Loading
Login
SelectServer
CreateAccount
这些流程都属于登录阶段。
它们共享登录阶段的基础资源。
从 Login 切到 SelectServer,通常只是界面变化。
从 SelectServer 返回 Login,也不应该卸载整个登录资源。
所以它们应该放在同一个 LoginScene 下面,作为不同的 SceneProcedure。
如果把它们拆成不同 GameScene,每次切换都要走资源卸载和重新加载流程,成本太高,也没有必要。
三、LoginScene 的例子
登录阶段可以划分成:
bash
LoginScene
├── Loading
├── Login
├── SelectServer
└── CreateAccount
这些都是登录阶段内部的流程变化。
Loading 可能负责初始化登录所需资源。
Login 负责账号输入和登录按钮。
SelectServer 负责服务器列表选择。
CreateAccount 负责注册或创建账号。
它们之间切换时,通常只需要:
bash
关闭当前界面
打开目标界面
切换当前流程状态
处理当前流程对应的按钮和网络请求
不需要卸载整个登录阶段资源。
所以它们适合作为 SceneProcedure。
四、MainScene 的例子
主场景可以划分成:
bash
MainScene
├── Lobby
├── WorldMap
├── Bag
└── Mall
这些流程都属于主场景内部。
Lobby 是大厅。
WorldMap 是世界地图。
Bag 是背包。
Mall 是商城。
玩家可能频繁在这些界面之间切换:
bash
大厅 -> 背包
背包 -> 商城
商城 -> 世界地图
世界地图 -> 大厅
这些切换不应该触发整个 MainScene 的资源卸载。
因为主界面资源、角色数据、玩家数据、部分 UI 资源通常还会继续使用。
所以它们更适合划分为 MainScene 下面的 SceneProcedure。
五、BattleScene 的例子
战斗场景可以划分成:
bash
BattleScene
├── BattleSetting
├── WaitForOther
├── MainFight
├── Pause
└── Settlement
这些流程都属于一次战斗过程。
BattleSetting 是战斗设置。
WaitForOther 是等待其他玩家或服务器同步。
MainFight 是正式战斗。
Pause 是暂停。
Settlement 是结算。
这些流程共享战斗资源。
例如:
bash
战斗角色
战斗地图
技能特效
战斗 UI
战斗数据
从 MainFight 切到 Pause,不能卸载战斗资源。
从 Pause 回到 MainFight,也不应该重新加载战斗对象。
从 MainFight 进入 Settlement,战斗资源可能还要用于结算展示。
所以这些都应该是 BattleScene 内部的 SceneProcedure。
真正离开战斗时,才从 BattleScene 切到其他 GameScene。
这时才适合清理战斗资源。
六、划分准则
判断一个状态应该是 GameScene,还是 SceneProcedure,可以看资源生命周期。
适合划分为 GameScene 的情况
bash
切换后当前阶段的大部分资源都不再需要
当前阶段有独立的资源加载和卸载边界
当前阶段有完整的进入和退出流程
当前阶段代表游戏的大状态
不同阶段之间不会频繁来回切换
例如:
bash
LoginScene
MainScene
BattleScene
这些阶段之间资源差异大。
切换时通常需要清理旧资源,加载新资源。
适合划分为 SceneProcedure 的情况
bash
仍然属于同一个大阶段
切换时主要是界面或逻辑状态变化
资源仍然可以继续复用
可能会频繁来回切换
不应该因为切换而触发资源卸载
例如:
bash
LoginScene 下的 Login / SelectServer / CreateAccount
MainScene 下的 Lobby / Bag / Mall / WorldMap
BattleScene 下的 MainFight / Pause / Settlement
这些流程之间更适合作为 SceneProcedure。
七、GameScene 切换时做什么
从一个 GameScene 切到另一个 GameScene,通常意味着当前大阶段结束。
所以需要执行比较完整的退出流程。
例如从 MainScene 进入 BattleScene:
bash
退出 MainScene 当前 SceneProcedure
关闭 MainScene 相关界面
中断 MainScene 相关延迟命令
取消 MainScene 相关事件监听
清理 MainScene 逻辑对象
释放 MainScene 独占资源
创建 BattleScene
加载 BattleScene 资源
启动 BattleScene 的初始 SceneProcedure
这里的关键是:
bash
GameScene 切换是大边界
它可以带来资源释放和重新加载。
所以不能把频繁切换的小流程都做成 GameScene。
八、SceneProcedure 切换时做什么
同一个 GameScene 内部切换 SceneProcedure,通常只是当前阶段内的流程变化。
例如 MainScene 中从 Lobby 切到 Bag:
bash
退出 Lobby 流程
关闭大厅局部界面
进入 Bag 流程
打开背包界面
刷新背包数据
这时不应该释放整个 MainScene 的资源。
也不应该销毁 MainScene 本身。
SceneProcedure 切换应该是轻量的。
它更多处理:
bash
界面显示隐藏
当前流程状态
按钮响应
局部数据刷新
局部网络请求
当前流程的进入和退出
这也是为什么 SceneProcedure 可以频繁切换。
九、SceneProcedure 可以是树形结构
一个 GameScene 内部的 SceneProcedure 不一定是平铺的。
它可以组成树形结构。
例如 MainScene 可以这样组织:
bash
MainScene
└── Root
├── Lobby
├── WorldMap
├── Bag
│ ├── BagMain
│ ├── BagUseItem
│ └── BagSort
└── Mall
├── MallMain
├── MallBuy
└── MallConfirm
Bag 可以是一个流程分组。
BagMain、BagUseItem、BagSort 是背包内部的子流程。
Mall 也可以继续拆成购买、确认等子流程。
战斗场景也可以这样组织:
bash
BattleScene
└── Root
├── BattleSetting
├── WaitForOther
├── MainFight
│ ├── PlayerTurn
│ ├── EnemyTurn
│ └── SkillSelect
├── Pause
└── Settlement
├── ShowReward
└── ConfirmExit
树形结构的作用是表达流程层级。
不是所有 Procedure 都必须在同一层。
一个大流程下面可以继续拆小流程。
十、树形 Procedure 的好处
树形 SceneProcedure 可以解决平铺流程越来越乱的问题。
例如战斗主流程里还有技能选择、目标选择、回合等待等子流程。
如果全部放在 BattleScene 第一层,会变成:
bash
BattleSetting
WaitForOther
MainFight
PlayerTurn
EnemyTurn
SkillSelect
TargetSelect
Pause
Settlement
ShowReward
ConfirmExit
层级会变得不清楚。
树形结构可以把它们归类:
bash
MainFight
PlayerTurn
EnemyTurn
SkillSelect
TargetSelect
Settlement
ShowReward
ConfirmExit
这样能看出哪些流程属于战斗中,哪些流程属于结算阶段。
父流程负责组织子流程。
子流程负责具体逻辑。
十一、资源不跟随 Procedure 卸载
SceneProcedure 的切换不能按资源场景的思路处理。
同一个 GameScene 内的资源通常由 GameScene 管理。
Procedure 只负责使用这些资源。
例如 BattleScene 中:
bash
MainFight
Pause
Settlement
这些流程都可能使用战斗地图、角色、战斗 UI、特效资源。
如果每次切换 Procedure 都卸载资源,会出现明显问题:
bash
Pause 回 MainFight 需要重新加载战斗资源
MainFight 到 Settlement 无法复用战斗结果展示资源
频繁切换导致加载开销过大
流程状态也容易被破坏
所以资源生命周期应该放在 GameScene 层。
Procedure 层只做逻辑和界面的切换。
十二、这个设计解决的问题
GameScene + SceneProcedure 主要解决的是流程边界问题。
它把游戏状态分成两层:
bash
GameScene:
大阶段
资源生命周期边界
切换时通常会卸载当前阶段资源
SceneProcedure:
阶段内流程
界面和逻辑状态
切换时通常不卸载资源
这样可以避免两类问题。
第一类是把小流程做成大场景:
bash
Login、SelectServer、CreateAccount 都做成 GameScene
导致频繁切换时重复加载和卸载资源
第二类是把大阶段塞进同一个场景:
bash
Login、Main、Battle 都做成 Procedure
导致资源边界不清楚
退出阶段时不知道该清理哪些资源
正确做法是按资源生命周期划分 GameScene,按阶段内流程划分 SceneProcedure。
十三、设计边界
GameScene 不应该过细。
下面这些通常不适合作为独立 GameScene:
bash
背包
商城
暂停
结算
选服
创建账号
它们更像当前阶段内的流程或界面。
SceneProcedure 也不应该承担跨阶段资源清理。
下面这些通常应该交给 GameScene:
bash
登录资源整体卸载
主场景资源整体卸载
战斗资源整体卸载
阶段级事件监听清理
阶段级对象销毁
GameScene 管大边界。
SceneProcedure 管小流程。
总结
MyFramework 中的 GameScene 和 SceneProcedure 可以按资源生命周期来划分。
GameScene 是逻辑场景,也是游戏的大阶段。
不同 GameScene 之间通常不共享资源。
从一个 GameScene 跳到另一个 GameScene 时,会退出当前阶段,并卸载当前阶段使用的资源。
SceneProcedure 是同一个 GameScene 内部的流程节点。
从一个 SceneProcedure 切到另一个 SceneProcedure,通常只是逻辑或界面变化,不会卸载资源。
例如:
bash
LoginScene
Loading
Login
SelectServer
CreateAccount
MainScene
Lobby
WorldMap
Bag
Mall
BattleScene
BattleSetting
WaitForOther
MainFight
Pause
Settlement
这套设计的重点是把"大阶段资源边界"和"阶段内流程变化"分开。
GameScene 决定资源什么时候整体进入和退出。
SceneProcedure 决定同一个阶段里当前走到哪个流程。
