using System.Collections.Generic; using TMPro; using UnityEngine; /// /// TMP 图片资源优先渲染器 /// /// 功能:让 TextMeshPro 在渲染字符时,优先查找 SpriteAsset(图片/艺术字), /// 找不到再 fallback 到 FontAsset(普通字体)。 /// /// 用法: /// 1. 把此脚本挂到带有 TMP_Text (TextMeshProUGUI / TextMeshPro) 的 GameObject 上 /// 2. 在 Inspector 中把需要优先的 SpriteAsset 拖进 PrioritySpriteAssets 列表 /// (列表顺序即优先级顺序,排第一的最优先) /// 3. 运行时自动生效;也可手动调用 Apply() 强制刷新 /// [AddComponentMenu("UI/TMP Sprite Priority")] [RequireComponent(typeof(TMP_Text))] public class TMP_SpritePriority : MonoBehaviour { [Header("优先渲染的 SpriteAsset 列表(顺序即优先级,第一个最高)")] [SerializeField] private List prioritySpriteAssets = new List(); [Header("是否在 Awake 时自动应用")] [SerializeField] private bool applyOnAwake = true; private TMP_Text _tmpText; private void Awake() { _tmpText = GetComponent(); if (applyOnAwake) Apply(); } /// /// 手动触发,将 SpriteAsset 插入 fallback 最前面,实现"Sprite 优先于 Font"渲染 /// public void Apply() { if (_tmpText == null) _tmpText = GetComponent(); if (_tmpText == null || prioritySpriteAssets == null || prioritySpriteAssets.Count == 0) return; // 取第一个作为 TMP_Text.spriteAsset(TMP 解析 / unicode 时优先查此处) _tmpText.spriteAsset = prioritySpriteAssets[0]; // 将剩余 SpriteAsset 插入主 SpriteAsset 的 fallback 链最前端 // TMP 查找 Sprite unicode 的顺序:spriteAsset → spriteAsset.fallbackSpriteAssets[0,1,...] → TMP Settings 默认 if (_tmpText.spriteAsset != null) { var fallbacks = _tmpText.spriteAsset.fallbackSpriteAssets; if (fallbacks == null) fallbacks = new List(); // 把列表[1]以后的 asset 依次插入到 fallback 前面(避免重复) for (int i = prioritySpriteAssets.Count - 1; i >= 1; i--) { var asset = prioritySpriteAssets[i]; if (asset == null || fallbacks.Contains(asset)) continue; fallbacks.Insert(0, asset); } _tmpText.spriteAsset.fallbackSpriteAssets = fallbacks; } // 强制 TMP 重新解析文本,让新优先级立即生效 _tmpText.SetAllDirty(); _tmpText.ForceMeshUpdate(); Debug.Log($"[TMP_SpritePriority] {gameObject.name} → 首选 SpriteAsset: {_tmpText.spriteAsset?.name},共 {prioritySpriteAssets.Count} 个图片资源已置为最高优先级"); } /// /// 恢复到系统默认(清除手动设置的 spriteAsset,交回 TMP Settings 管理) /// public void Reset() { if (_tmpText == null) return; _tmpText.spriteAsset = null; // null = 使用 TMP Settings 中的默认 SpriteAsset _tmpText.SetAllDirty(); _tmpText.ForceMeshUpdate(); } }