FixSystemCenter.OnSingletonDestroy 在场景销毁阶段访问的 CameraKit、 BubbleSlotKit 可能已清理,且 Director.QuitCurrentMode 协程依赖的 对象可能已拆除。改为判空访问,并新增 Director.Reset 直接清理状态。
129 lines
4.5 KiB
C#
129 lines
4.5 KiB
C#
using System.Collections;
|
|
using AibisDream.Framework;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.FixSystem
|
|
{
|
|
/// <summary>
|
|
/// Directs Fix scene mode transitions. This is a scene cue board, not a gameplay state machine:
|
|
/// cues orchestrate cameras, timelines, UI masks, bubbles and interaction setup.
|
|
/// </summary>
|
|
public class FixSceneDirector
|
|
{
|
|
public FixSceneMode CurrentMode { get; private set; }
|
|
public string CurrentArgs { get; private set; } = "";
|
|
public bool HasMode { get; private set; }
|
|
public bool IsTransitioning { get; private set; }
|
|
|
|
private IFixSceneCue _currentCue;
|
|
|
|
public IEnumerator Init(FixSceneMode initMode)
|
|
{
|
|
yield return TransitionInternal(initMode, "", FixTransitionMode.Immediate);
|
|
}
|
|
|
|
public IEnumerator TransitionTo(FixSceneMode nextMode, string args = "")
|
|
{
|
|
yield return TransitionInternal(nextMode, args, FixTransitionMode.Animated);
|
|
}
|
|
|
|
public IEnumerator TransitionToImmediate(FixSceneMode nextMode, string args = "")
|
|
{
|
|
yield return TransitionInternal(nextMode, args, FixTransitionMode.Immediate);
|
|
}
|
|
|
|
public IEnumerator QuitCurrentMode()
|
|
{
|
|
if (_currentCue != null)
|
|
{
|
|
var transition = new FixTransition(CurrentMode, FixSceneMode.Default, "", FixTransitionMode.Animated);
|
|
yield return _currentCue.Exit(transition);
|
|
}
|
|
|
|
CurrentArgs = "";
|
|
_currentCue = null;
|
|
CurrentMode = FixSceneMode.Default;
|
|
HasMode = false;
|
|
IsTransitioning = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears director state without running cue exits. Used while the owning scene is
|
|
/// being destroyed, when cue dependencies may already have been torn down.
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
CurrentArgs = "";
|
|
_currentCue = null;
|
|
CurrentMode = FixSceneMode.Default;
|
|
HasMode = false;
|
|
IsTransitioning = false;
|
|
}
|
|
|
|
private IEnumerator TransitionInternal(FixSceneMode nextMode, string args, FixTransitionMode mode)
|
|
{
|
|
if (IsTransitioning && mode == FixTransitionMode.Animated)
|
|
{
|
|
Debug.LogWarning($"[FixSceneDirector] Transition ignored while another transition is running: {CurrentMode} -> {nextMode}");
|
|
yield break;
|
|
}
|
|
|
|
if (HasMode && CurrentMode.Equals(nextMode))
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
IsTransitioning = true;
|
|
|
|
var transition = new FixTransition(HasMode ? CurrentMode : null, nextMode, args, mode);
|
|
|
|
if (mode == FixTransitionMode.Animated && _currentCue != null)
|
|
{
|
|
yield return _currentCue.Exit(transition);
|
|
}
|
|
|
|
_currentCue = CreateCue(nextMode);
|
|
CurrentMode = nextMode;
|
|
CurrentArgs = args ?? "";
|
|
HasMode = true;
|
|
|
|
EnumEventSystem.Global.Send(EventEnum.FixSceneModeChanged, nextMode);
|
|
|
|
if (mode == FixTransitionMode.Immediate)
|
|
{
|
|
yield return _currentCue.EnterImmediate(transition);
|
|
}
|
|
else
|
|
{
|
|
yield return _currentCue.Enter(transition);
|
|
}
|
|
|
|
IsTransitioning = false;
|
|
}
|
|
|
|
private static IFixSceneCue CreateCue(FixSceneMode nextMode)
|
|
{
|
|
return nextMode switch
|
|
{
|
|
FixSceneMode.Default => new DefaultCue(),
|
|
FixSceneMode.Clinic => new ClinicCue(),
|
|
FixSceneMode.BodyModule => new BodyModuleCue(),
|
|
FixSceneMode.Memory => new MemoryCue(),
|
|
FixSceneMode.Eye => new EyeCue(),
|
|
FixSceneMode.UF => new UfCue(),
|
|
FixSceneMode.Expression => new ExpressionCue(),
|
|
FixSceneMode.Emo => new EmoCue(),
|
|
FixSceneMode.Op => new OpCue(),
|
|
FixSceneMode.EmoCut => new EmoCutCue(),
|
|
FixSceneMode.MemoryCut => new MemoryCutCue(),
|
|
FixSceneMode.LogicCut => new LogicCutCue(),
|
|
FixSceneMode.Dream => new DreamCue(),
|
|
FixSceneMode.AnalysisMode => new AnalysisModeCue(),
|
|
FixSceneMode.Sales => new SalesCue(),
|
|
FixSceneMode.BlockPuzzle => new BlockPuzzleCue(),
|
|
_ => new DefaultCue()
|
|
};
|
|
}
|
|
}
|
|
}
|