标记 #option_prompt 的台词不再进入普通台词流程,由 OptionView 暂存并在下一组 Dream Options 出现时显示在选项上方,同时通过 新增 LineHistoryAppend 事件加入对话历史。OnelineOptions 支持 提示语文本与独立选项根节点,并改为按实例追踪销毁按钮。
165 lines
5.0 KiB
C#
165 lines
5.0 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using AibisDream.Framework;
|
|
using AibisDream.Utility;
|
|
using UnityEngine;
|
|
using Yarn.Unity;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public class OptionView : DialoguePresenterBase
|
|
{
|
|
[SerializeField] private DefaultOptions defaultOptions;
|
|
[SerializeField] private CenterOptions centerOptions;
|
|
[SerializeField] private OnelineOptions onelineOptions;
|
|
[SerializeField] private DialogViewType defaultViewType = DialogViewType.StandardBubble;
|
|
|
|
private OptionExploreTracker? _tracker;
|
|
private LineInfo? _pendingOptionPrompt;
|
|
|
|
private void Awake()
|
|
{
|
|
_tracker = new OptionExploreTracker();
|
|
_tracker.Bind();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
_tracker?.Unbind();
|
|
_tracker = null;
|
|
}
|
|
|
|
public override YarnTask OnDialogueStartedAsync()
|
|
{
|
|
ClearPendingOptionPrompt();
|
|
return YarnTask.CompletedTask;
|
|
}
|
|
|
|
public override YarnTask OnDialogueCompleteAsync()
|
|
{
|
|
ClearPendingOptionPrompt();
|
|
HideDialog();
|
|
return YarnTask.CompletedTask;
|
|
}
|
|
|
|
public override YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token)
|
|
{
|
|
if (line.IsOptionPromptLine())
|
|
{
|
|
_pendingOptionPrompt = LineInfo.Generate(line);
|
|
}
|
|
else
|
|
{
|
|
ClearPendingOptionPrompt();
|
|
}
|
|
|
|
return YarnTask.CompletedTask;
|
|
}
|
|
|
|
public override void OnNodeExit(string nodeName)
|
|
{
|
|
ClearPendingOptionPrompt();
|
|
}
|
|
|
|
public void LoadBubbles(BubbleSlotGroupData data)
|
|
{
|
|
defaultViewType = data.dialogViewType;
|
|
}
|
|
|
|
public override async YarnTask<DialogueOption?> RunOptionsAsync(DialogueOption[] dialogueOptions, LineCancellationToken cancellationToken)
|
|
{
|
|
EnumEventSystem.Global.Send(DialogEventEnum.OptionShow);
|
|
var optionSelectedSource = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
|
|
var (nodeName, tags) = DialogController.Instance != null
|
|
? DialogController.Instance.GetCurrentNodeContext()
|
|
: (null, (IReadOnlyList<string>)Array.Empty<string>());
|
|
|
|
var options = DialogOption.GeneOptions(
|
|
dialogueOptions,
|
|
_tracker,
|
|
nodeName,
|
|
tags,
|
|
optionId => optionSelectedSource.TrySetResult(optionId));
|
|
|
|
var viewType = GetCurrentViewType(options);
|
|
var optionPrompt = _pendingOptionPrompt;
|
|
ClearPendingOptionPrompt();
|
|
|
|
switch (viewType)
|
|
{
|
|
case DialogViewType.Default:
|
|
case DialogViewType.StandardBubble:
|
|
defaultOptions.ShowOptions(options);
|
|
break;
|
|
case DialogViewType.OnelineBox:
|
|
onelineOptions.ShowOptions(options, optionPrompt?.lineText);
|
|
if (optionPrompt.HasValue)
|
|
{
|
|
EnumEventSystem.Global.Send(
|
|
DialogEventEnum.LineHistoryAppend,
|
|
optionPrompt.Value);
|
|
}
|
|
break;
|
|
case DialogViewType.CenterOption:
|
|
centerOptions.ShowOptions(options);
|
|
break;
|
|
default:
|
|
Debug.Log($"选项{options[0].Character.key}没有找到选项框{viewType}");
|
|
break;
|
|
}
|
|
|
|
using var cancellationReg = cancellationToken.NextContentToken.Register(() =>
|
|
{
|
|
optionSelectedSource.TrySetCanceled(cancellationToken.NextContentToken);
|
|
});
|
|
|
|
try
|
|
{
|
|
var selectedOptionId = await optionSelectedSource.Task;
|
|
foreach (var dialogueOption in dialogueOptions)
|
|
{
|
|
if (dialogueOption.DialogueOptionID == selectedOptionId)
|
|
{
|
|
return dialogueOption;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
catch (TaskCanceledException)
|
|
{
|
|
HideDialog();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void ClearPendingOptionPrompt()
|
|
{
|
|
_pendingOptionPrompt = null;
|
|
}
|
|
|
|
private DialogViewType GetCurrentViewType(DialogOption[] options)
|
|
{
|
|
var optionViewType = options[0].Character.dialogViewType;
|
|
|
|
if (optionViewType == DialogViewType.Default)
|
|
{
|
|
return defaultViewType;
|
|
}
|
|
|
|
return optionViewType;
|
|
}
|
|
|
|
public void HideDialog()
|
|
{
|
|
defaultOptions.HideOptions();
|
|
onelineOptions.HideOptions();
|
|
centerOptions.HideOptions();
|
|
}
|
|
}
|
|
}
|