Files
Cielonos/Assets/Scripts/SLSUtilities/Narrative/UI/AdvancedOptionItem.cs
SoulliesOfficial 8186f54e90 新场景,剧情
2026-06-02 12:55:39 -04:00

129 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}
}