Files
Cielonos/Assets/Scripts/SLSUtilities/UI/InputGlyphParser.cs
SoulliesOfficial 6d7ebc5825 Passion & UI
2026-06-12 17:11:39 -04:00

81 lines
3.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 System.Text.RegularExpressions;
namespace SLSUtilities.UI
{
/// <summary>
/// 将文本中的 [Token] 标记替换为 TMP &lt;sprite&gt; 富文本标签,
/// 用于在 TMP_Text 中内联显示按键图标。
/// <para>
/// Token 支持两种形式:
/// <list type="bullet">
/// <item><b>直接按键名</b>[Q]、[LMB]、[ArrowDown] — 直接映射到 SpriteAsset 中的 sprite name</item>
/// <item><b>Input Action 名</b>[Interact]、[MainWeaponPrimary] — 通过 <see cref="InputBindingResolver"/>
/// 解析为当前绑定的按键 glyph token需先调用 <see cref="InputBindingResolver.Initialize"/></item>
/// </list>
/// 语法示例:
/// <list type="bullet">
/// <item>[Q]+[RMB] → Q 键 + 右键图标(+ 作为普通文本保留)</item>
/// <item>Hold [E] → "Hold " 为普通文本E 键为图标</item>
/// <item>按 [Interact] 拾取 → 自动解析为当前绑定的按键图标</item>
/// </list>
/// </para>
/// </summary>
public static class InputGlyphParser
{
/// <summary>默认关联的 TMP SpriteAsset 名称。</summary>
public const string DefaultSpriteAsset = "InputGlyphs";
/// <summary>
/// 匹配 [Token] 模式。
/// \w+ 涵盖字母、数字、下划线,足以覆盖所有 Token 名Q, LMB, ArrowDown, F12, Interact 等)。
/// </summary>
private static readonly Regex TokenPattern =
new Regex(@"\[(\w+)\]", RegexOptions.Compiled);
/// <summary>
/// 将文本中的 [Token] 标记解析为 TMP sprite 富文本标签。
/// 如果 <see cref="InputBindingResolver"/> 已初始化Token 会先尝试解析为 Action 名对应的按键。
/// </summary>
/// <param name="rawText">
/// 原始文本,可包含 [Token] 标记。
/// 例如 "[Q]+[RMB]"、"Hold [E]"、"按 [Interact] 拾取"。
/// </param>
/// <param name="spriteAssetName">
/// 要引用的 TMP SpriteAsset 名称。
/// 传入 null 或空字符串时,生成不指定 asset 的短格式标签
/// (需在 TMP Settings 中配置默认 Sprite Asset
/// </param>
/// <returns>替换后的富文本字符串。输入为 null 或空时原样返回。</returns>
public static string Parse(string rawText, string spriteAssetName = DefaultSpriteAsset)
{
if (string.IsNullOrEmpty(rawText))
return rawText;
bool useResolver = InputBindingResolver.IsInitialized;
bool hasAssetName = !string.IsNullOrEmpty(spriteAssetName);
return TokenPattern.Replace(rawText, match =>
{
string token = match.Groups[1].Value;
// 通过 InputBindingResolver 解析 Action 名 → glyph token
string resolvedToken = useResolver
? InputBindingResolver.ResolveToken(token)
: token;
return hasAssetName
? $"<sprite=\"{spriteAssetName}\" name=\"{resolvedToken}\">"
: $"<sprite name=\"{resolvedToken}\">";
});
}
/// <summary>
/// 检查文本是否包含任何 [Token] 标记。
/// </summary>
public static bool ContainsGlyphs(string text)
{
return !string.IsNullOrEmpty(text) && TokenPattern.IsMatch(text);
}
}
}