fix(scene-mgmt): 修复场景加载后立即开对话的时序问题

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-01 12:05:46 +08:00
co-authored by Cursor
parent 93a5076369
commit da436479db
8 changed files with 117 additions and 8 deletions
@@ -19,7 +19,7 @@ namespace AibisDream.FixSystem
public IEnumerator Init(FixSceneMode initMode)
{
yield return TransitionInternal(initMode, "", FixTransitionMode.Animated);
yield return TransitionInternal(initMode, "", FixTransitionMode.Immediate);
}
public IEnumerator TransitionTo(FixSceneMode nextMode, string args = "")
+17 -2
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections;
using AibisDream;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.SaveSystem;
@@ -7,12 +8,16 @@ using UnityEngine;
namespace AibisDream.FixSystem
{
public class FixSystemCenter : Singleton<FixSystemCenter>
public class FixSystemCenter : Singleton<FixSystemCenter>, ISceneDialogueGate
{
public FixSceneMode CurrentMode => Director.CurrentMode;
public FixSceneMode defaultMode = FixSceneMode.Default;
public bool IsDirectorReady { get; private set; }
public bool IsDialogueReady => IsDirectorReady;
public static IOCContainer SystemDic = new();
public static FixSceneContext Context;
public static FixSceneDirector Director;
@@ -22,6 +27,7 @@ namespace AibisDream.FixSystem
SystemDic ??= new IOCContainer();
Context = new FixSceneContext(SystemDic);
Director = new FixSceneDirector();
IsDirectorReady = false;
}
private void Start()
@@ -31,11 +37,19 @@ namespace AibisDream.FixSystem
return;
}
StartCoroutine(Director.Init(defaultMode));
StartCoroutine(InitDirectorRoutine());
}
private IEnumerator InitDirectorRoutine()
{
IsDirectorReady = false;
yield return Director.Init(defaultMode);
IsDirectorReady = true;
}
public override void OnSingletonDestroy()
{
IsDirectorReady = false;
CameraKit.Instance.RemoveAllCam();
BubbleSlotKit.Instance.RemoveAll();
GameManager.Instance.StartCoroutine(Director.QuitCurrentMode());
@@ -77,6 +91,7 @@ namespace AibisDream.FixSystem
}
yield return Director.TransitionToImmediate(mode, dto.args ?? "");
IsDirectorReady = true;
}
}
}
@@ -153,9 +153,9 @@ namespace AibisDream.FixSystem
if (!CameraKit.Instance.EqualToCameraState(CameraEnum.DreamCamera))
{
yield return CameraKit.Instance.SwitchCamera(CameraEnum.DreamCamera);
BubbleSlotKit.Instance.LoadBubbles(BubbleSlotEnum.Open);
}
BubbleSlotKit.Instance.LoadBubbles(BubbleSlotEnum.Open);
}
public IEnumerator EnterImmediate(FixTransition transition)
+49
View File
@@ -110,9 +110,57 @@ namespace AibisDream
ChapterController.Instance.UnlockChapter(_currentTalkSceneSo.Value);
yield return UIManager.Instance.GetPanel<PlayToolPanel>().FadeInAsync(0.5f);
yield return SceneLoader.Instance.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName);
yield return WaitForSceneDialogueReady();
DialogController.Instance.StartDialog(_currentTalkSceneSo.Value.yarnProject);
}
/// <summary>
/// 等待新场景 Awake/Start 完成,并等待场景协调器(Fix / Subway / Outside 等)就绪后再开对话。
/// </summary>
private static IEnumerator WaitForSceneDialogueReady()
{
yield return null;
if (SceneHasDialogueGate())
{
while (HasPendingDialogueGate())
{
yield return null;
}
}
else
{
yield return null;
}
}
private static bool SceneHasDialogueGate()
{
return FixSystemCenter.Instance != null
|| SubwayCenter.Instance != null
|| OutsideCenter.Instance != null;
}
private static bool HasPendingDialogueGate()
{
if (FixSystemCenter.Instance is ISceneDialogueGate { IsDialogueReady: false })
{
return true;
}
if (SubwayCenter.Instance is ISceneDialogueGate { IsDialogueReady: false })
{
return true;
}
if (OutsideCenter.Instance is ISceneDialogueGate { IsDialogueReady: false })
{
return true;
}
return false;
}
public void PauseGame()
{
// 系统暂停
@@ -234,6 +282,7 @@ namespace AibisDream
ChapterController.Instance.UnlockChapter(_currentTalkSceneSo.Value);
yield return UIManager.Instance.GetPanel<PlayToolPanel>().FadeInAsync();
yield return SceneLoader.Instance.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName);
yield return WaitForSceneDialogueReady();
DialogController.Instance.StartDialog(_currentTalkSceneSo.Value.yarnProject);
}
else
@@ -0,0 +1,10 @@
namespace AibisDream
{
/// <summary>
/// 场景级协调器:在 StartDialog 之前完成相机、Bubble 等初始化。
/// </summary>
public interface ISceneDialogueGate
{
bool IsDialogueReady { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fec846dedd21efd4eafc0f3fc6ff6f82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -3,11 +3,20 @@ using AibisDream.Kit;
namespace AibisDream
{
public class OutsideCenter : Singleton<OutsideCenter>
public class OutsideCenter : Singleton<OutsideCenter>, ISceneDialogueGate
{
public bool IsDialogueReady { get; private set; }
public override void OnSingletonInit()
{
IsDialogueReady = false;
BubbleSlotKit.Instance.LoadBubbles(BubbleSlotEnum.Outside);
IsDialogueReady = true;
}
public override void OnSingletonDestroy()
{
IsDialogueReady = false;
}
}
}
@@ -10,7 +10,7 @@ using Yarn.Unity;
namespace AibisDream
{
public class SubwayCenter : Singleton<SubwayCenter>
public class SubwayCenter : Singleton<SubwayCenter>, ISceneDialogueGate
{
#region
@@ -20,6 +20,8 @@ namespace AibisDream
public static StateMachine<OutSideState> StateMachine { get; private set; }
public bool IsDialogueReady { get; private set; }
private string _currentNewsSpriteId;
#endregion
@@ -27,7 +29,20 @@ namespace AibisDream
public override void OnSingletonInit()
{
StateMachine = new StateMachine<OutSideState>(CreateState);
StartCoroutine(StateMachine.Init(OutSideState.Subway));
IsDialogueReady = false;
StartCoroutine(InitStateMachineRoutine());
}
private IEnumerator InitStateMachineRoutine()
{
IsDialogueReady = false;
yield return StateMachine.Init(OutSideState.Subway);
IsDialogueReady = true;
}
public override void OnSingletonDestroy()
{
IsDialogueReady = false;
}
private static IState<OutSideState> CreateState(OutSideState nextState, string arg = "")