feat: 存档系统增加退出节点保存时机

This commit is contained in:
2026-07-26 19:59:56 +08:00
parent 4caf70b554
commit 82c15e8f48
18 changed files with 1195 additions and 159 deletions
@@ -22,6 +22,8 @@ namespace AibisDream
private string _currentNodeName;
private string[] _currentNodeTags;
private PendingExitCheckpoint _pendingExitCheckpoint;
private long _dialogueFlowVersion;
private void Start()
{
@@ -37,12 +39,7 @@ namespace AibisDream
EnumEventSystem.Global.Send(InteractionEventEnum.DialogStart);
});
_dialogueRunner.onDialogueComplete.AddListener(() =>
{
DialogueActivityChanged?.Invoke(false);
EnumEventSystem.Global.Send(InteractionEventEnum.DialogEnd);
ClearCurrentNodeContext();
});
_dialogueRunner.onDialogueComplete.AddListener(OnDialogueComplete);
_dialogueRunner.onNodeStart.AddListener(OnNodeStart);
_dialogueRunner.onNodeComplete.AddListener(OnNodeComplete);
@@ -61,6 +58,8 @@ namespace AibisDream
private void OnDisable()
{
CancelPendingExitCheckpoint("DialogController disabled", logIfPending: false);
SingleCastEventSystem.Global.Unregister(DialogEventEnum.StartNode);
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionStarted, ResetAdvanceMode);
@@ -92,6 +91,7 @@ namespace AibisDream
/// <param name="yarnProject">Yarn组</param>
public void StartDialog(YarnProject yarnProject)
{
CancelPendingExitCheckpoint("StartDialog 切换 YarnProject");
PrepareYarnProjectForDialog(yarnProject);
_dialogueRunner.SetProject(yarnProject);
_ = _dialogueRunner.StartDialogue("Start");
@@ -104,6 +104,8 @@ namespace AibisDream
public IEnumerator StopDialogRoutine()
{
CancelPendingExitCheckpoint("StopDialogRoutine", logIfPending: false);
if (_dialogueRunner != null && _dialogueRunner.IsDialogueRunning)
{
yield return _dialogueRunner.Stop();
@@ -122,6 +124,7 @@ namespace AibisDream
public void LoadDialog(YarnProject yarnProject)
{
CancelPendingExitCheckpoint("LoadDialog 切换 YarnProject");
PrepareYarnProjectForDialog(yarnProject);
_dialogueRunner.SetProject(yarnProject);
}
@@ -189,6 +192,10 @@ namespace AibisDream
private void OnNodeStart(string nodeName)
{
_dialogueFlowVersion++;
CancelPendingExitCheckpoint(
$"节点 {nodeName} 已开始,说明之前的退出保存路径继续运行 Yarn",
incrementFlowVersion: false);
UpdateCurrentNodeContext(nodeName);
var projectId = _dialogueRunner?.YarnProject?.name;
@@ -200,7 +207,12 @@ namespace AibisDream
return;
}
if (!SavePointEvaluator.OnNodeStartForAutoSave(projectId, nodeName, tags, out var reason))
if (!SavePointEvaluator.OnNodeStartForSavePolicy(
projectId,
nodeName,
tags,
out var policy,
out var reason))
{
if (reason == SavePointRejectReason.DetourResume)
{
@@ -210,15 +222,86 @@ namespace AibisDream
return;
}
StartCoroutine(SaveRestoreOrchestrator.AutoSaveRoutine(nodeName));
if (policy.Timing == NodeSaveTiming.DialogueExit)
{
_pendingExitCheckpoint = new PendingExitCheckpoint
{
ProjectId = projectId,
NodeName = nodeName,
FlowVersion = _dialogueFlowVersion
};
return;
}
if (policy.Timing == NodeSaveTiming.NodeEnter)
{
StartCoroutine(SaveRestoreOrchestrator.AutoSaveRoutine(nodeName));
}
}
private void OnNodeComplete(string nodeName)
{
SavePointEvaluator.OnNodeComplete(_dialogueRunner?.YarnProject?.name, nodeName);
if (_pendingExitCheckpoint != null
&& string.Equals(_pendingExitCheckpoint.NodeName, nodeName, StringComparison.Ordinal)
&& string.Equals(
_pendingExitCheckpoint.ProjectId,
_dialogueRunner?.YarnProject?.name,
StringComparison.Ordinal))
{
_pendingExitCheckpoint.IsNodeComplete = true;
}
ClearCurrentNodeContext();
}
private void OnDialogueComplete()
{
DialogueActivityChanged?.Invoke(false);
EnumEventSystem.Global.Send(InteractionEventEnum.DialogEnd);
ClearCurrentNodeContext();
var checkpoint = _pendingExitCheckpoint;
_pendingExitCheckpoint = null;
if (checkpoint?.IsNodeComplete != true)
{
return;
}
var expectedFlowVersion = checkpoint.FlowVersion;
StartCoroutine(SaveRestoreOrchestrator.DialogueExitSaveRoutine(
checkpoint.NodeName,
checkpoint.ProjectId,
() => _dialogueFlowVersion == expectedFlowVersion
&& (_dialogueRunner == null || !_dialogueRunner.IsDialogueRunning)));
}
private void CancelPendingExitCheckpoint(
string reason,
bool logIfPending = true,
bool incrementFlowVersion = true)
{
if (incrementFlowVersion)
{
_dialogueFlowVersion++;
}
if (_pendingExitCheckpoint == null)
{
return;
}
if (logIfPending)
{
Debug.LogWarning(
$"[DialogController] 取消 interaction/save_on_exit 退出存档: " +
$"node={_pendingExitCheckpoint.NodeName}, reason={reason}");
}
_pendingExitCheckpoint = null;
}
private void UpdateCurrentNodeContext(string nodeName)
{
if (_dialogueRunner == null || _dialogueRunner.Dialogue == null)
@@ -241,6 +324,14 @@ namespace AibisDream
_currentNodeTags = null;
}
private sealed class PendingExitCheckpoint
{
public string ProjectId;
public string NodeName;
public long FlowVersion;
public bool IsNodeComplete;
}
#region
public BindProperty<AdvanceMode> advanceMode = new(new AdvanceMode());