Unity MyFramework 用法说明(二十八):使用 SceneSystem 管理 Unity 场景资源
前面介绍的GameScene和SceneProcedure负责管理游戏的业务流程但它们并不直接加载 Unity 的.unity场景文件。真正负责 Unity 场景注册、异步加载、显示隐藏和资源卸载的是SceneSystem。项目地址https://github.com/ZHOURUIH/MyFramework一、GameScene 和 SceneSystem 的区别这两个系统的名字相似但职责完全不同。GameScene 管理游戏业务流程 SceneProcedure 管理一个业务流程中的不同阶段 SceneSystem 管理真正的 Unity Scene 资源 SceneInstance 封装一个已经加载的 Unity Scene例如进入战斗时业务流程可能是MainSceneLoading ↓ MainSceneGaming ↓ MainSceneExit这是GameScene管理的内容。而下面这些操作属于SceneSystem加载 Battle.unity 显示或隐藏 Battle_Root 将 Battle 设置为 Active Scene 卸载 Battle.unity 释放场景目录中的资源二者通常配合使用SceneProcedure 决定什么时候进入战斗 ↓ SceneSystem 负责加载战斗场景资源二、创建 SceneInstance每个需要由SceneSystem管理的 Unity 场景都可以创建一个对应的SceneInstance。例如战斗场景public class BattleSceneInstance : SceneInstance { public override void init() { base.init(); // 获取场景中的固定节点 // 初始化场景逻辑 } public override void onShow() { // 场景被显示 } public override void onHide() { // 场景被隐藏 } public override void update(float elapsedTime) { // 只有场景处于显示状态时才会更新 } public override void lateUpdate(float elapsedTime) { } public override void destroy() { // 清理场景相关引用 base.destroy(); } }SceneInstance主要保存Unity Scene 对象 场景根节点 场景名称 场景逻辑类型 加载状态 加载进度回调 加载完成回调 是否显示 是否设置为主场景只有处于显示状态的场景才会执行update()和lateUpdate()。三、场景必须有固定根节点SceneSystem加载完成后会查找场景名_Root假设场景文件名为Battle.unity场景层级应该是Battle └── Battle_Root ├── Environment ├── Light ├── MonsterRoot ├── EffectRoot └── Other框架通过Battle_Root控制整个场景的显示和隐藏。内部加载完成后会执行scene.setRoot( findRootGameObject( scene.getName() _Root, true));因此根节点名称必须正确并且最好保证场景中的所有内容都放在这个根节点下。调用mSceneSystem.hideScene(Battle);本质上不会卸载场景而是关闭Battle_Root四、注册场景场景使用前需要注册using static FrameBaseHotFix; public static class SceneRegister { public static BattleSceneInstance mBattleScene; public static void registeAll() { mSceneSystem.registeScene( typeof(BattleSceneInstance), Scene/Battle/Battle.unity, (instance) { mBattleScene instance as BattleSceneInstance; }); } }然后在GameHotFix.registerAll()中调用protected override void registerAll() { LayoutRegisterHotFix.registeAll(); SceneRegister.registeAll(); }注册信息包括SceneInstance 类型 场景文件路径 场景实例变化回调路径相对于Assets/GameResources并且必须以.unity结尾Scene/Battle/Battle.unity场景名称会自动从文件名中获得Battle.unity ↓ Battle回调会在场景实例创建时传入对应的SceneInstance卸载时传入null因此可以用来保存和清空场景引用。这个回调不表示 Unity 场景已经加载完成。真正的加载完成逻辑应使用loadSceneAsync()的完成回调。五、异步加载场景SceneSystem只提供异步场景加载protected CustomAsyncOperation mLoadOperation; protected void loadBattleScene() { mLoadOperation mSceneSystem.loadSceneAsync( Battle, true, true, onBattleSceneLoaded, onBattleSceneLoading); } protected void onBattleSceneLoading(float progress) { mUILoading?.setLoadPercent(progress); } protected void onBattleSceneLoaded() { log(战斗场景加载完成); }参数含义为Battle 注册时生成的场景名称 true 加载完成后立即显示 true 加载完成后设置为 Unity Active Scene onBattleSceneLoaded 加载完成回调 onBattleSceneLoading 加载进度回调返回的CustomAsyncOperation可以继续加入Waiting AsyncTaskGroup CustomMultiAsyncOperation例如同时等待场景、角色和服务器数据Waiting waiting mWaitingManager.createWaiting( onPrepareFinished); waiting.addAsyncOperation( mSceneSystem.loadSceneAsync( Battle, true, true, null)); waiting.addCondition( () mPlayerCreated); waiting.addCondition( () mServerDataReady);六、内部为什么统一使用 Additive框架加载场景时固定使用SceneManager.LoadSceneAsync( scene.getName(), LoadSceneMode.Additive);也就是所有场景都以叠加模式加载。这样SceneSystem才能同时管理多个场景基础场景 战斗场景 角色展示场景 家园场景 预览场景加载新场景时不会由 Unity 自动销毁之前的场景而是由框架决定哪些场景继续显示 哪些场景暂时隐藏 哪些场景真正卸载SceneManager.LoadScene()虽然名字看起来是同步加载但函数返回时场景不一定已经完全可用因此框架不再提供表面上的同步接口。七、场景加载的内部流程loadSceneAsync()的主要流程是根据场景名查找注册信息 ↓ 创建对应的 SceneInstance ↓ 通过 ResourceManager 预加载场景 AssetBundle ↓ 使用 Additive 异步加载 Unity Scene ↓ 持续发送加载进度 ↓ 获取 Unity Scene 对象 ↓ 查找 场景名_Root ↓ 执行 SceneInstance.init() ↓ 根据参数显示或隐藏场景 ↓ 执行加载完成回调核心逻辑可以简化为AsyncOperation operation SceneManager.LoadSceneAsync( scene.getName(), LoadSceneMode.Additive); scene.setScene( SceneManager.GetSceneByName( scene.getName())); scene.setRoot( findRootGameObject( scene.getName() _Root, true)); scene.init();SceneInstance.init()中还会扫描场景节点使用的 Shader保证动态加载后的材质能够正确找到对应 Shader。八、显示和隐藏场景隐藏场景mSceneSystem.hideScene(Battle);隐藏只会关闭根节点并调用BattleSceneInstance.onHide();场景仍然保留在内存中之后可以快速重新显示。显示场景mSceneSystem.showScene(Battle);默认参数为showScene( Battle, true, true);表示隐藏其他已加载场景 显示 Battle 将 Battle 设置为主场景需要同时显示多个场景时mSceneSystem.showScene( CharacterPreview, false, false);表示不隐藏其他场景也不修改当前主场景。单独设置主场景mSceneSystem.setMainScene( Battle);它会调用 Unity 的SceneManager.SetActiveScene(...);九、隐藏和卸载不是一回事隐藏场景mSceneSystem.hideScene(Battle);结果是Scene 仍然已加载 资源仍然保留 Battle_Root 被关闭 停止 SceneInstance 更新 可以快速再次显示卸载场景mSceneSystem.unloadScene(Battle);结果是通知场景引用回调传入 null 销毁 SceneInstance 调用 SceneManager.UnloadSceneAsync 从已加载场景列表中移除 卸载场景目录中的资源因此短时间后还会重新使用的场景可以先隐藏。确定离开并且短时间内不会再回来时再真正卸载。十、场景目录与资源卸载unloadScene()默认参数为mSceneSystem.unloadScene( Battle, true);第二个参数表示是否卸载场景所在目录中的资源。框架会调用mResourceManager.unloadPath( getFilePath(scenePath));因此推荐按场景组织独占资源GameResources └── Scene └── Battle ├── Battle.unity ├── Model ├── Material ├── Texture └── Effect这个目录中最好只放战斗场景独占资源。多个场景共享的资源应放到公共目录避免场景卸载时把资源目录一起清理。不希望卸载目录资源时mSceneSystem.unloadScene( Battle, false);卸载除指定场景以外的其他场景mSceneSystem.unloadOtherScene( Battle);适合在进入新区域后清理旧场景。十一、总结MyFramework 中与场景相关的职责分为两层GameScene SceneProcedure 管理游戏业务流程 SceneSystem SceneInstance 管理 Unity 场景资源SceneSystem的基本使用流程是1. 创建 SceneInstance 子类 2. 为 Unity 场景添加 场景名_Root 3. 使用 registeScene 注册场景 4. 使用 loadSceneAsync 异步加载 5. 使用 showScene 和 hideScene 控制显示 6. 使用 setMainScene 设置 Active Scene 7. 不再使用时调用 unloadScene所有场景统一使用 Additive 模式加载再由框架控制显示、更新和卸载。这样业务流程只需要决定什么时候进入或离开场景不需要在各个模块中重复处理 Unity Scene、根节点、加载进度和场景资源释放。

相关新闻

从0到1理解Elixir-Slack架构:State管理与消息分发原理

从0到1理解Elixir-Slack架构:State管理与消息分发原理

从0到1理解Elixir-Slack架构:State管理与消息分发原理 【免费下载链接】Elixir-Slack Slack real time messaging and web API client in Elixir 项目地址: https://gitcode.com/gh_mirrors/el/Elixir-Slack Elixir-Slack是一个基于Elixir语言开发的Slack实时…

2026/8/5 19:16:35 阅读更多 →
Linux日志管理学习笔记

Linux日志管理学习笔记

文章目录前言一、先搞懂:Linux日志到底是什么?1.1 日志的核心作用1.2 日志都存在哪?二、核心日志服务:rsyslogd2.1 工作原理2.2 两个核心概念:日志类型 & 日志级别(1)日志类型(F…

2026/8/5 19:16:35 阅读更多 →
Path of Building PoE2:流放之路2角色构建的免费离线规划器终极指南

Path of Building PoE2:流放之路2角色构建的免费离线规划器终极指南

Path of Building PoE2:流放之路2角色构建的免费离线规划器终极指南 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 还在为《流放之路2》复杂的角色构建系统感到困惑吗?每次调整天…

2026/8/5 19:16:35 阅读更多 →

最新新闻

Umi-OCR免费离线批量识别终极指南:如何用一款软件解决所有图片文字提取需求

Umi-OCR免费离线批量识别终极指南:如何用一款软件解决所有图片文字提取需求

Umi-OCR免费离线批量识别终极指南:如何用一款软件解决所有图片文字提取需求 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成…

2026/8/5 20:01:52 阅读更多 →
5个关键步骤掌握VideoDownloadHelper:开源视频下载插件完全指南

5个关键步骤掌握VideoDownloadHelper:开源视频下载插件完全指南

5个关键步骤掌握VideoDownloadHelper:开源视频下载插件完全指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经遇到过…

2026/8/5 20:01:52 阅读更多 →
从零到一:用Python在GTA5中打造自动驾驶AI的完整指南

从零到一:用Python在GTA5中打造自动驾驶AI的完整指南

从零到一:用Python在GTA5中打造自动驾驶AI的完整指南 【免费下载链接】pygta5 Explorations of Using Python to play Grand Theft Auto 5. 项目地址: https://gitcode.com/gh_mirrors/py/pygta5 想象一下,让AI在《侠盗猎车手5》的虚拟世界中自由…

2026/8/5 20:01:52 阅读更多 →
浏览器自动化战略决策指南:AI驱动与代码驱动方案的全景评估

浏览器自动化战略决策指南:AI驱动与代码驱动方案的全景评估

浏览器自动化战略决策指南:AI驱动与代码驱动方案的全景评估 【免费下载链接】playwright-skill Claude Code Skill for browser automation with Playwright. Model-invoked - Claude autonomously writes and executes custom automation for testing and validati…

2026/8/5 20:01:52 阅读更多 →
EB Garamond 12:重新定义学术排版的终极开源字体解决方案

EB Garamond 12:重新定义学术排版的终极开源字体解决方案

EB Garamond 12:重新定义学术排版的终极开源字体解决方案 【免费下载链接】EBGaramond12 项目地址: https://gitcode.com/gh_mirrors/eb/EBGaramond12 在数字时代寻找一款既经典又现代的字体?EB Garamond 12 将16世纪的经典Garamond字体完美融入…

2026/8/5 20:01:51 阅读更多 →
实时音频分析服务器:让声音数据驱动创意应用

实时音频分析服务器:让声音数据驱动创意应用

实时音频分析服务器:让声音数据驱动创意应用 【免费下载链接】Realtime_PyAudio_FFT Realtime audio analysis in Python to extract audio features from streaming audio and send them over OSC to any client app. 项目地址: https://gitcode.com/gh_mirrors/…

2026/8/5 20:00:51 阅读更多 →

日新闻

Java缓存框架:JetCache

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:00:43 阅读更多 →
AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/5 0:00:43 阅读更多 →
AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

更多请点击: https://kaifayun.com 第一章:AI生成素描效果 AI生成素描效果是计算机视觉与风格迁移技术融合的典型应用,其核心在于将彩色照片或RGB图像转换为具有手绘质感、明暗对比强烈、边缘清晰的单色素描图像。该过程通常依赖于深度学习模…

2026/8/5 0:00:43 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →