129 lines
4.5 KiB
C#
129 lines
4.5 KiB
C#
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using Yarn.Unity;
|
||
using Yarn.Markup;
|
||
using TMPro;
|
||
|
||
namespace SLSUtilities.Narrative.UI
|
||
{
|
||
/// <summary>
|
||
/// 高级选项项,继承自官方 OptionItem。
|
||
/// 支持解析选项中的 #desc: 和 #fail: 元数据标签,
|
||
/// 通过 OptionTooltipUI 显示选项提示,
|
||
/// 以及使用 [kw] Yarn Markup 标签高亮关键词。
|
||
/// </summary>
|
||
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 = $"<s>{processed}</s>";
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|