using System.Globalization; using UnityEngine; namespace AibisDream { [CreateAssetMenu( fileName = "NarrativeTextStyleConfig", menuName = AibisAssetMenus.NarrativeTextStyle)] public sealed class NarrativeTextStyleConfig : ScriptableObject { [Header("语义颜色")] [SerializeField] private Color _asideColor = new Color32(0x5F, 0x5F, 0x5F, 0xFF); [SerializeField] private Color _termColor = new Color32(0x52, 0xB6, 0xFF, 0xFF); [SerializeField] private Color _keyColor = new Color32(0xFF, 0xB2, 0x00, 0xFF); [Header("节奏与效果")] [SerializeField, Min(0f)] private float _commaPauseSeconds = 0.2f; [SerializeField] private string _ulmEffectPrefix = "[[vertexp d=0.05 bot]]"; [SerializeField] private string _jokeOpenTag = ""; [SerializeField] private string _jokeCloseTag = ""; public Color AsideColor => _asideColor; public Color TermColor => _termColor; public Color KeyColor => _keyColor; public float CommaPauseSeconds => _commaPauseSeconds; public string UlmEffectPrefix => _ulmEffectPrefix; public string JokeOpenTag => _jokeOpenTag; public string JokeCloseTag => _jokeCloseTag; } public static class NarrativeTextStyleExpander { private static readonly Color DefaultAsideColor = new Color32(0x5F, 0x5F, 0x5F, 0xFF); private static readonly Color DefaultTermColor = new Color32(0x52, 0xB6, 0xFF, 0xFF); private static readonly Color DefaultKeyColor = new Color32(0xFF, 0xB2, 0x00, 0xFF); public static string Expand(string text, NarrativeTextStyleConfig config) { if (string.IsNullOrEmpty(text)) { return text; } Color asideColor = config != null ? config.AsideColor : DefaultAsideColor; Color termColor = config != null ? config.TermColor : DefaultTermColor; Color keyColor = config != null ? config.KeyColor : DefaultKeyColor; float commaPause = config != null ? config.CommaPauseSeconds : 0.2f; string ulmPrefix = config != null ? config.UlmEffectPrefix : "[[vertexp d=0.05 bot]]"; string jokeOpen = config != null ? config.JokeOpenTag : ""; string jokeClose = config != null ? config.JokeCloseTag : ""; return text .Replace("[[aside]]", ColorOpen(asideColor)) .Replace("[[/aside]]", "") .Replace("[[term]]", ColorOpen(termColor)) .Replace("[[/term]]", "") .Replace("[[key]]", ColorOpen(keyColor)) .Replace("[[/key]]", "") .Replace( "[[comma-pause]]", $"") .Replace("[[ulm]]", ulmPrefix) .Replace("[[joke]]", jokeOpen) .Replace("[[/joke]]", jokeClose); } private static string ColorOpen(Color color) { // This runs after Yarn has parsed the source, so the hash must not // carry Yarn's source-level escape into TextMesh Pro. return $""; } } }