场景切换系统

ScenesManager 是 Fink Framework 内置的统一场景管理模块,提供:

  • 同步切换场景
  • 异步切换场景(await / callback / 句柄方式)
  • 自动进度平滑(0~1)
  • 场景切换前自动清理(对象池 / UI / 声音 / 事件系统 / 资源缓存)
  • 无需继承 MonoBehaviour,可随时调用

路径:Runtime/Scene/ScenesManager.cs


1. 设计目标

  • 提供统一、强大的场景加载 API
  • 支持三种异步模式:await / callback / handle(句柄方式)
  • 进度回调为 0~1 的平滑值
  • 切换场景前自动清理所有框架模块
  • 保证新场景生命周期正常执行(内部会自动延迟 1 帧)

2. 同步切换场景

适用于轻量场景或编辑器工具。

2.1 通过场景名加载

ScenesManager.Instance.LoadScene("GameScene", () =>
{
    Debug.Log("Scene Loaded");
});

2.2 通过场景 ID 加载

ScenesManager.Instance.LoadScene(1, () =>
{
    Debug.Log("Scene Loaded");
});

同步方式会在瞬间完成切换,不适合加载大场景。


3. 异步切换场景(推荐方式)

场景异步切换同时支持三种写法。

3.1 await 方式(最常用)

await ScenesManager.Instance.LoadSceneAsync("GameScene");

ID 方式:

await ScenesManager.Instance.LoadSceneAsync(1);

3.2 回调方式(带进度)

ScenesManager.Instance.LoadSceneAsyncCallback(
    "GameScene",
    onComplete: () =>
    {
        Debug.Log("Scene Loaded!");
    },
    onProgress: p =>
    {
        Debug.Log("Progress: " + p);
    });

ID 方式同理:

ScenesManager.Instance.LoadSceneAsyncCallback(
    1,
    onComplete: () => Debug.Log("Done"),
    onProgress: p => Debug.Log(p));

3.3 句柄方式(可监听进度 / 完成事件)

var op = ScenesManager.Instance.LoadSceneHandle("GameScene");

op.Completed += o =>
{
    Debug.Log("Scene Loaded!");
};

await op.WaitUntilDone();

ID 版本:

var op = ScenesManager.Instance.LoadSceneHandle(2);

SceneOperation 提供:

字段功能
float Progress异步加载进度(平滑 0~1)
bool IsDone是否完成加载
UnityAction Completed完成事件
WaitUntilDone()await 等待完成

4. 进度回调说明(onProgress)

Unity 的 AsyncOperation.progress 最大只到 0.9。

框架内部已做平滑:

p = Percent01(asyncOp.progress, 0, 0.9);

你收到的进度永远是:

0.0  →  1.0(平滑过渡)

并且最终会补一次:

onProgress(1f);

5. 场景切换完成回调(onComplete)

加载完成后,框架会自动执行:

await UniTask.Yield();

以确保:XR Origin、UI、新场景物体 Awake/Start、Input System等都在同一帧正确初始化,然后才触发: onComplete();


6. 自动清理机制(场景切换前)

每次切换场景之前,框架会自动清理:

AudioManager.Instance.ClearSound();   
PoolManager.Instance.CleanPool();     
UIManager.Instance.ClearAllPanels();  
EventManager.Instance.ClearAllEvent();
ResManager.Instance.ClearDic();       
System.GC.Collect();                  

清理机制的意义

  • 防止旧场景对象残留
  • 防止池对象泄漏
  • 防止音效继续播放
  • 防止重复事件监听
  • 释放未使用资源,降低内存占用
  • 用户无需手动调用,所有切换 API 已自动整合。

7. 常用 API 汇总

方法说明
LoadScene(name)同步切换
LoadScene(id)同步切换
LoadSceneAsync(name)await 异步切换
LoadSceneAsync(id)await 异步切换
LoadSceneAsyncCallback(name, onComplete, onProgress)回调方式
LoadSceneAsyncCallback(id, onComplete, onProgress)回调方式
LoadSceneHandle(name)返回 SceneOperation
LoadSceneHandle(id)返回 SceneOperation

8. 注意事项

目标场景必须加入 Build Settings

场景加载过程中不要立即依赖新场景对象(建议放到 onComplete)

如果使用自动事件绑定(EventAutoBinder),事件将在场景切换时自动删除

若使用加载 UI,可直接绑定 SceneOperation.Progress 显示


9. 总结

ScenesManager 为框架提供了稳定、统一、可扩展的场景切换能力,配合对象池、UI 系统、音频系统等模块,可以构建完整的场景过渡流程。