diff --git a/Assets/GameContent/Common/NarrativeTextStyleConfig.asset b/Assets/GameContent/Common/NarrativeTextStyleConfig.asset new file mode 100644 index 000000000..cab9519cb --- /dev/null +++ b/Assets/GameContent/Common/NarrativeTextStyleConfig.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0df9c4430661480e9c647ea7e22a92b6, type: 3} + m_Name: NarrativeTextStyleConfig + m_EditorClassIdentifier: + _asideColor: {r: 0.37254903, g: 0.37254903, b: 0.37254903, a: 1} + _termColor: {r: 0.32156864, g: 0.7137255, b: 1, a: 1} + _keyColor: {r: 1, g: 0.69803923, b: 0, a: 1} + _commaPauseSeconds: 0.2 + _ulmEffectPrefix: '[[vertexp d=0.05 bot]]' + _jokeOpenTag: + _jokeCloseTag: diff --git a/Assets/GameContent/Common/NarrativeTextStyleConfig.asset.meta b/Assets/GameContent/Common/NarrativeTextStyleConfig.asset.meta new file mode 100644 index 000000000..c886ed5c2 --- /dev/null +++ b/Assets/GameContent/Common/NarrativeTextStyleConfig.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b14d9162528749f68d1229a5de940dab +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AibisDream.Menus/AibisAssetMenus.cs b/Assets/Scripts/AibisDream.Menus/AibisAssetMenus.cs index 8e291fec3..044cf2672 100644 --- a/Assets/Scripts/AibisDream.Menus/AibisAssetMenus.cs +++ b/Assets/Scripts/AibisDream.Menus/AibisAssetMenus.cs @@ -8,6 +8,7 @@ namespace AibisDream public const string Root = "AIBIS"; public const string NarrativeTalkScene = Root + "/叙事/对话场景"; + public const string NarrativeTextStyle = Root + "/叙事/文本样式"; public const string FrameAnimationGraph = Root + "/角色动画/帧动画 Graph"; public const string FrameClip = Root + "/角色动画/帧动画 Clip"; public const string BubbleStyle = Root + "/对话 UI/气泡样式"; diff --git a/Assets/Scripts/Dialog System/AibisLineProvider.cs b/Assets/Scripts/Dialog System/AibisLineProvider.cs index d6c648f66..825e9baef 100644 --- a/Assets/Scripts/Dialog System/AibisLineProvider.cs +++ b/Assets/Scripts/Dialog System/AibisLineProvider.cs @@ -29,6 +29,9 @@ namespace AibisDream [SerializeField, Language] private string _fallbackLocaleCode = System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName; + [SerializeField] + private NarrativeTextStyleConfig _narrativeTextStyle; + public string AssetLocaleCode { get => _assetLocaleCode; @@ -82,7 +85,9 @@ namespace AibisDream line.Substitutions[i] = LocalizationKit.LocalizeParam(line.Substitutions[i]); } - // 保留旧 LocalisedLineProvider 的文本转义处理 + // 先展开项目级语义标记,再保留旧 LocalisedLineProvider 的文本转义处理。 + // ULM 的 [[vertexp ...]] 会由 Escape 转成 Text Animator 使用的花括号标签。 + text = NarrativeTextStyleExpander.Expand(text, _narrativeTextStyle); text = CommonUtil.Escape(text); var parseResult = lineParser.ParseString(Yarn.Markup.LineParser.ExpandSubstitutions(text, line.Substitutions), LocaleCode); diff --git a/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs b/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs new file mode 100644 index 000000000..6de5f1b78 --- /dev/null +++ b/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs @@ -0,0 +1,78 @@ +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 $""; + } + } +} diff --git a/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs.meta b/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs.meta new file mode 100644 index 000000000..427912324 --- /dev/null +++ b/Assets/Scripts/Dialog System/NarrativeTextStyleConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0df9c4430661480e9c647ea7e22a92b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: