using UnityEngine; using UnityEngine.EventSystems; using Yarn.Unity; using Yarn.Markup; using TMPro; namespace SLSUtilities.Narrative.UI { /// /// 高级选项项,继承自官方 OptionItem。 /// 支持解析选项中的 #desc: 和 #fail: 元数据标签, /// 通过 OptionTooltipUI 显示选项提示, /// 以及使用 [kw] Yarn Markup 标签高亮关键词。 /// public class AdvancedOptionItem : OptionItem { public string TooltipDesc { get; private set; } public string TooltipFail { get; private set; } public TMP_Text GetTextComponent() => text; // 追踪当前是否是由鼠标指针触发的选中状态 // OnPointerEnter 在 OnSelect 之前同步设置此标记,OnDeselect 清除 private bool _pointerEntered = false; public override DialogueOption Option { get => base.Option; set { // 调用基类 setter:设置 _option、interactable 和 ApplyStyle // 注意:基类也会设置 text.text,我们稍后会覆盖它 base.Option = value; // 解析 Tooltip 元数据标签 (#desc: / #fail:) TooltipDesc = null; TooltipFail = null; if (value.Line.Metadata != null) { YarnTagParser.Parse(value.Line.Metadata, out var kvTags, out _); if (kvTags.TryGetValue("desc", out string desc)) { TooltipDesc = desc.Replace("_", " "); } if (kvTags.TryGetValue("fail", out string fail)) { TooltipFail = fail.Replace("_", " "); } } // 选项文本高亮处理: // 仅通过 ProcessWithMarkup 处理手动标记的 [kw] 或 [kw id="..."] 标签。 // 不进行正则自动扫描(只高亮明确被 [kw] 标记的部分,与台词表现一致)。 if (text != null) { string processed = KeywordProcessor.ProcessWithMarkup(value.Line.TextWithoutCharacterName); if (disabledStrikeThrough && !value.IsAvailable) { processed = $"{processed}"; } text.text = processed; } } } public override void OnPointerEnter(PointerEventData eventData) { // 在调用 base.OnPointerEnter(其中会同步调用 OnSelect)之前 // 设置标记,使 OnSelect 能知道这是鼠标触发的 _pointerEntered = true; base.OnPointerEnter(eventData); } public override void OnPointerExit(PointerEventData eventData) { base.OnPointerExit(eventData); // 鼠标离开后清除,但不关闭 Tooltip(由 OptionTooltipUI 的文本区域检测控制) _pointerEntered = false; } public override void OnPointerClick(PointerEventData eventData) { // 只有当点击的是鼠标左键时,才允许选择并推进此选项,阻断鼠标右键的选择触发 if (eventData.button == PointerEventData.InputButton.Left) { base.OnPointerClick(eventData); } } public override void OnSelect(BaseEventData eventData) { base.OnSelect(eventData); // 将"是否为鼠标触发"传递给 OptionTooltipUI,用于决定定位方式 OptionTooltipUI.Instance?.OnOptionSelected(this, _pointerEntered); } public override void OnDeselect(BaseEventData eventData) { base.OnDeselect(eventData); _pointerEntered = false; OptionTooltipUI.Instance?.OnOptionDeselected(this); } protected override void OnEnable() { base.OnEnable(); if (KeywordTooltipUI.Instance != null && text != null) { KeywordTooltipUI.Instance.RegisterExternalText(text); } } protected override void OnDisable() { base.OnDisable(); if (KeywordTooltipUI.Instance != null && text != null) { KeywordTooltipUI.Instance.UnregisterExternalText(text); } } } }