feat(fix-system): 为读档添加状态机即时切换与快照支持

This commit is contained in:
2026-06-11 21:49:18 +08:00
parent c67d988365
commit 4bb0215f3d
7 changed files with 125 additions and 22 deletions
@@ -30,6 +30,9 @@ namespace AibisDream.FixSystem
public bool inHotErr;
private int _heatValue;
/// <summary>获取当前 BodyModule 分组(Body/Head)。</summary>
public ModuleState GetCurrentModuleState() => _data.moduleState;
private int HeatValue
{
get => _heatValue;
+36 -20
View File
@@ -10,12 +10,10 @@ namespace AibisDream.FixSystem
{
public class FixStateMachine
{
public FixState CurState => _curState.GetState;
private IState<FixState> _curState;
public FixState CurState => _stateMachine.CurState;
private StateMachine<FixState> _stateMachine;
private FixSystemData _data;
public FixStateMachine(FixSystemData data)
@@ -39,6 +37,24 @@ namespace AibisDream.FixSystem
yield return _stateMachine.SwitchState(nextState, args);
}
/// <summary>
/// 读档专用:跳过动画直接切换状态。不触发 Exit/Enter 动画,只执行 EnterImmediate。
/// 通过 <see cref="StateMachine{FixState}.SetStateImmediate"/> 同步 _stateMachine 内部状态,避免与正常 SwitchState 分叉。
/// </summary>
public IEnumerator SwitchStateImmediate(FixState nextState, string args = "")
{
if (_stateMachine.HasState && CurState.Equals(nextState)) yield break;
_stateMachine.SetStateImmediate(nextState, args);
_data.curState = nextState;
_data.args = args;
if (_stateMachine.CurrentStateObj is IFixState fixState)
yield return fixState.EnterImmediate();
else
yield return _stateMachine.CurrentStateObj.Enter();
}
public IEnumerator QuitState()
{
_data.curState = FixState.Default;
@@ -93,7 +109,7 @@ namespace AibisDream.FixSystem
BlockPuzzle = 17
}
public struct DefaultState : IState<FixState>
public struct DefaultState : IFixState
{
public FixState GetState => FixState.Default;
@@ -112,7 +128,7 @@ namespace AibisDream.FixSystem
}
}
public struct ClinicState : IState<FixState>
public struct ClinicState : IFixState
{
public FixState GetState => FixState.Clinic;
@@ -138,7 +154,7 @@ namespace AibisDream.FixSystem
}
}
public struct BodyModuleState : IState<FixState>
public struct BodyModuleState : IFixState
{
private string _args;
@@ -195,7 +211,7 @@ namespace AibisDream.FixSystem
}
}
public struct UfState : IState<FixState>
public struct UfState : IFixState
{
public FixState GetState => FixState.UF;
@@ -239,7 +255,7 @@ namespace AibisDream.FixSystem
}
}
public struct EyeState : IState<FixState>
public struct EyeState : IFixState
{
public FixState GetState => FixState.Eye;
@@ -292,7 +308,7 @@ namespace AibisDream.FixSystem
}
}
public struct MemoryState : IState<FixState>
public struct MemoryState : IFixState
{
public FixState GetState => FixState.Memory;
@@ -336,7 +352,7 @@ namespace AibisDream.FixSystem
}
}
public struct ExpressionState : IState<FixState>
public struct ExpressionState : IFixState
{
public FixState GetState => FixState.Expression;
@@ -388,7 +404,7 @@ namespace AibisDream.FixSystem
}
}
public struct EmoState : IState<FixState>
public struct EmoState : IFixState
{
public FixState GetState => FixState.Emo;
@@ -420,7 +436,7 @@ namespace AibisDream.FixSystem
}
}
public struct OpState : IState<FixState>
public struct OpState : IFixState
{
public FixState GetState => FixState.Op;
@@ -444,7 +460,7 @@ namespace AibisDream.FixSystem
}
}
public struct DreamState : IState<FixState>
public struct DreamState : IFixState
{
public FixState GetState => FixState.Dream;
@@ -471,7 +487,7 @@ namespace AibisDream.FixSystem
}
}
public struct EmoCutState : IState<FixState>
public struct EmoCutState : IFixState
{
public FixState GetState => FixState.EmoCut;
@@ -521,7 +537,7 @@ namespace AibisDream.FixSystem
}
}
public struct MemoryCutState : IState<FixState>
public struct MemoryCutState : IFixState
{
public FixState GetState => FixState.MemoryCut;
@@ -571,7 +587,7 @@ namespace AibisDream.FixSystem
}
}
public struct LogicCutState : IState<FixState>
public struct LogicCutState : IFixState
{
public FixState GetState => FixState.LogicCut;
@@ -619,7 +635,7 @@ namespace AibisDream.FixSystem
}
}
public struct AnalysisModeState : IState<FixState>
public struct AnalysisModeState : IFixState
{
public FixState GetState => FixState.AnalysisMode;
@@ -671,7 +687,7 @@ namespace AibisDream.FixSystem
}
}
public struct SalesState : IState<FixState>
public struct SalesState : IFixState
{
private string _systemView;
@@ -742,7 +758,7 @@ namespace AibisDream.FixSystem
}
}
public struct BlockPuzzleState : IState<FixState>
public struct BlockPuzzleState : IFixState
{
private const string puzzleName = "Game2";
private const float blockPuzzleScale = 1.6f;
@@ -3,6 +3,7 @@ using System.Collections;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.SaveSystem;
using UnityEngine;
namespace AibisDream.FixSystem
{
@@ -45,6 +46,45 @@ namespace AibisDream.FixSystem
public static FixStateMachine StateMachine;
#endregion
#region
/// <summary>捕获 Fix 场景宏观快照。</summary>
public FixSnapshotDto CaptureSnapshot()
{
var bodyModule = SystemDic.Get<BodyModuleSystem>();
var eyeSystem = SystemDic.Get<EyeSystem>();
var repairManager = RepairSystemManager.Instance;
return new FixSnapshotDto
{
state = StateMachine.CurState.ToString(),
args = _data.args,
moduleState = bodyModule?.GetCurrentModuleState().ToString(),
eyeColorState = eyeSystem?.GetCurrentColorState().ToString(),
isSystemOn = FixPanelSystem.Instance?.IsSystemOn ?? false,
currentRepairSystemType = repairManager?.GetCurrentSystemType()?.Name
};
}
/// <summary>还原 Fix 场景宏观快照。调用 EnterImmediate 跳过动画。</summary>
public IEnumerator RestoreSnapshot(FixSnapshotDto dto)
{
if (dto == null || string.IsNullOrEmpty(dto.state))
{
yield break;
}
if (!Enum.TryParse<FixState>(dto.state, out var state))
{
Debug.LogWarning($"[FixSystemCenter] 无法解析 FixState: {dto.state}");
yield break;
}
yield return StateMachine.SwitchStateImmediate(state, dto.args ?? "");
}
#endregion
}
[Serializable]
+18
View File
@@ -0,0 +1,18 @@
using System.Collections;
using AibisDream.Framework;
namespace AibisDream.FixSystem
{
/// <summary>
/// Fix 场景专用状态接口,扩展 <see cref="IState{FixState}"/> 增加读档快速进入入口。
/// </summary>
public interface IFixState : IState<FixState>
{
/// <summary>读档专用:跳过 camera/timeline/fade 等动画,直接到达终态。</summary>
IEnumerator EnterImmediate()
{
// P1 占位默认实现:后续各 State 可覆盖为具体逻辑
yield break;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7d5df9cd63e8db54da758ad165a5a6b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -6,11 +6,13 @@ namespace AibisDream.Framework
public class StateMachine<T> where T : Enum
{
public T CurState => _curState.GetState;
public bool HasState => _curState != null;
public IState<T> CurrentStateObj => _curState;
public event Action<T> OnStateSwitch;
private IState<T> _curState;
private readonly Func<T, string, IState<T>> _createState;
public StateMachine(Func<T, string, IState<T>> createState)
{
_createState = createState;
@@ -30,7 +32,16 @@ namespace AibisDream.Framework
OnStateSwitch?.Invoke(nextState);
yield return _curState.Enter();
}
/// <summary>
/// 强制设置内部状态对象,不触发 Exit / Enter / OnStateSwitch。
/// 用于读档等需要绕过正常状态过渡的场景。
/// </summary>
public void SetStateImmediate(T state, string args = "")
{
_curState = _createState.Invoke(state, args);
}
public IEnumerator QuitState()
{
yield return _curState?.Exit();
@@ -31,6 +31,10 @@ namespace AibisDream
public ViewCameraManager cameraManager;
private IEyeStateEffect eyeStateEffect;
private EyeData _eyeData = new();
/// <summary>获取当前 Eye 颜色阶段。</summary>
public EyeData.EyeColorState GetCurrentColorState() => _eyeData.currentState;
private Tween hsvShiftTween;
private MouseFollowAndZoom mouseFollowAndZoom;