#nullable enable using System; using System.Collections.Generic; using System.Threading.Tasks; using AibisDream.Framework; 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 void Awake() { _tracker = new OptionExploreTracker(); _tracker.Bind(); } private void OnDestroy() { _tracker?.Unbind(); _tracker = null; } public override YarnTask OnDialogueStartedAsync() { return YarnTask.CompletedTask; } public override YarnTask OnDialogueCompleteAsync() { HideDialog(); return YarnTask.CompletedTask; } public override YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token) { return YarnTask.CompletedTask; } public void LoadBubbles(BubbleSlotGroupData data) { defaultViewType = data.dialogViewType; } public override async YarnTask RunOptionsAsync(DialogueOption[] dialogueOptions, LineCancellationToken cancellationToken) { EnumEventSystem.Global.Send(DialogEventEnum.OptionShow); var optionSelectedSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var (nodeName, tags) = DialogController.Instance != null ? DialogController.Instance.GetCurrentNodeContext() : (null, (IReadOnlyList)Array.Empty()); var options = DialogOption.GeneOptions( dialogueOptions, _tracker, nodeName, tags, optionId => optionSelectedSource.TrySetResult(optionId)); var viewType = GetCurrentViewType(options); switch (viewType) { case DialogViewType.Default: case DialogViewType.StandardBubble: defaultOptions.ShowOptions(options); break; case DialogViewType.OnelineBox: onelineOptions.ShowOptions(options); 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) { return 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(); } } }