优化

场景加载

场景切换在GameManager里面,用的Async

为什么我感觉用UniTask之后比之前奇怪,加载的时候先删掉了人物,再切换场景?

是正常现象,但“看起来怪”通常不是 UniTask 本身有问题,而是 LoadSceneAsync 把原来同步切场景里看不见的中间过程暴露出来了

你会感觉成“先删掉人物,再切场景”,核心原因一般是这几个:

  1. LoadSceneAsync 期间游戏还在继续跑帧
    以前如果你用的是 SceneManager.LoadScene(…),切场景几乎是硬切,你看不到中间态。
    但改成 UniTask + LoadSceneAsync(…) 后,Unity 会一边加载,一边继续更新/渲染,所以“旧场景开始销毁,新场景还没完全接上”的过程会被你看到。

  2. 旧人物本来就属于旧场景对象
    你的 Player 不是 DontDestroyOnLoad 常驻对象,而是场景内对象。
    所以一旦开始 LoadSceneAsync(…, LoadSceneMode.Single),旧场景进入卸载阶段时,旧人物就会先被销毁。
    如果这时黑幕没完全盖住,或者相机还在渲染,你就会看到“人先没了”。

  3. await 链里多出来的“可见帧”
    我之前给你的 UniTask 版里有这种节奏:

    • await loadOperation.ToUniTask(…)
    • await UniTask.WaitUntil(() => _sceneLoadedEventRaised, …)
    • await UniTask.NextFrame(…)

    这类写法本身是为了稳住时序,但副作用是:
    如果黑幕没有在整个加载阶段保持完全遮挡,就更容易看到中间空档。

  4. 黑幕是否真的先盖满,很关键
    如果 SceneFader 的 CanvasGroup.alpha、Sorting Order、Canvas 层级、或者 FadeOut 完成前就开始 LoadSceneAsync,都会出现“玩家消失了,但黑幕还没完全盖住”的视觉问题。
    这样你就会误以为是 UniTask 把人物先删了。

一句话总结:
不是 UniTask 在“先删人”,而是 LoadSceneAsync 让你看见了旧场景卸载的过渡帧;同步切场景时这段你以前看不到。

通常怎么修:

  • 在开始 LoadSceneAsync 之前,先确保黑幕已经完全不透明
  • 加载期间一直保持黑幕,不要提前 FadeIn
  • 加载时锁输入、锁相机跟随
  • 不要在加载过程里依赖旧 CurrentPlayer
  • 如果特别在意观感,可以用 allowSceneActivation = false 先预加载,黑幕盖好后再激活场景

通常黑幕

电梯

当我的人物在MouseHole5上电梯时,如果人物站上电梯的位置太靠近两侧,视觉上就会有一种被电梯夹住的感觉,这个时候如果电梯向上移动就会感觉很奇怪,应该怎么处理?

  1. 不要再用“平台碰撞体”直接作为“允许起梯区域”。
    在电梯内部单独做一个更窄的 RideSafeZone,宽度只取轿厢可站区域的中间一段。人物只有进入这个安全区,才允许关门和上升。

  2. 起梯前先“自动居中”,再上升。
    玩家进安全区后,不要立刻上升。先把人物 X 缓动到一个固定站位点,时长控制在 0.15~0.25s,看起来会像“角色自己站稳”。这一步做完再关门、再起梯,视觉会自然很多。

  3. 上升期间锁住横向输入。
    起梯后应该锁 external input,而不只是锁跳跃。否则人物在上升过程中仍可能保留横向移动/输入,继续往边上蹭,怪异感还会存在。

  4. 如果还想更稳,再加一个“边缘容错修正”。
    如果人物触发起梯时离站位点只差一点点,不用提示失败,直接吸附到站位点;只有偏得特别离谱时,才不给起梯。这样既不卡玩家,也不会穿帮。

重生

以后扩展怎么做

以后你新增一个重开出生点,比如 Basement:

  1. 在目标场景里再放一个 SceneSpawnPoint,比如 restart_basement
  2. 在 SettingsCanvas 的 _restartRoutes 里加一条新规则
  3. 如果是“同一个场景但不同剧情回不同地方”,就在这条规则里填 requiredFlagsAllTrue / requiredFlagsAllFalse
  4. 把更具体的规则放前面,通用规则放后面