Files
Obsidian_Unity/项目学习/ARPG/ARPG游戏开发问题.md
T
2026-05-03 14:06:26 +08:00

2.9 KiB
Raw Blame History

1.加载界面卡顿

我们在点击开始游戏的时候加载到游戏界面的过程中会卡顿,他会先卡顿一秒然后才进入到加载页面,他的问题就是SceneManager.LoadSceneAsync(). Unity 的所有核心逻辑,包括UI渲染、输入处理和大部分游戏逻辑的执行,都发生在主线程上。如果主线程被一个耗时很长的任务(比如一次性从硬盘读取大量数据并解压)卡住,那么整个应用程序就会冻结——画面停止渲染,UI无法响应。这就是你遇到的“卡顿”。

  • SceneManager.LoadSceneAsync() 的“陷阱”

    • 用途:它的设计初衷是为了在后台线程加载场景资源,避免长时间冻结主线程。

    • 原理:虽然名字里有 Async(异步),但它在被调用的第一帧,仍然需要在主线程上执行一些同步的准备工作。这包括:从磁盘定位场景文件、读取场景的元数据、准备反序列化等等。如果你的场景很大,有很多GameObject和资源引用,这个“准备工作”本身就可能耗时几十到几百毫秒,足以造成肉眼可见的卡顿。

    • 好/不好:这个函数本身是好的,是异步加载的唯一标准方式。但不好的地方在于,开发者很容易误解它,以为调用它的瞬间就是完全异步的。 代码1的问题剖析:

// 在主线程的某个 Update 或按钮点击事件中被调用
public void Load(string next)
{
    LoadingViewController.Instance.Open(); // 1. 请求打开UI
    LoginViewController.Instance.Close();

    StartCoroutine(LoadSceneAsync(next));   // 2. 启动协程
}

private IEnumerator LoadSceneAsync(string next)
{
    // 3. 协程在下一帧开始执行
    var operation = SceneManager.LoadSceneAsync(next); // 4. 问题点!
    // ...
}

执行流程与卡顿原因:

  1. 点击按钮(第N帧): Load() 方法被调用。它请求打开 Loading UI。但这只是一个请求,真正的UI绘制要等到这一帧的渲染阶段。

  2. 启动协程StartCoroutine 启动了协程,但协程的代码要到**下一帧(第N+1帧)**的 Update 阶段才会开始执行。

  3. 协程开始(第N+1帧): 协程的第一行代码 SceneManager.LoadSceneAsync(next) 被执行。

  4. 主线程阻塞:此时,LoadSceneAsync 的同步准备阶段开始,它会阻塞主线程。如果场景很大,主线程可能会在这里卡住 1-2 秒。

  5. 卡顿后果:因为主线程被阻塞,第N帧请求绘制的 Loading UI 根本没有机会被渲染出来。所以你的游戏画面会停留在上一个界面(LoginView),直到 LoadSceneAsync 的同步阶段完成。

  6. 加载飞快:当卡顿结束后,LoadSceneAsync 已经把大部分重活都干完了,operation.progress 的值可能直接就是 0.8 或接近 0.9。所以你的进度条看起来一瞬间就加载完了。