Files
5.24BuYu/Assets/Scripts/TMP_SpritePriority.cs
T
2026-05-18 18:39:11 +08:00

91 lines
3.3 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.Collections.Generic;
using TMPro;
using UnityEngine;
/// <summary>
/// TMP 图片资源优先渲染器
///
/// 功能:让 TextMeshPro 在渲染字符时,优先查找 SpriteAsset(图片/艺术字),
/// 找不到再 fallback 到 FontAsset(普通字体)。
///
/// 用法:
/// 1. 把此脚本挂到带有 TMP_Text (TextMeshProUGUI / TextMeshPro) 的 GameObject 上
/// 2. 在 Inspector 中把需要优先的 SpriteAsset 拖进 PrioritySpriteAssets 列表
/// (列表顺序即优先级顺序,排第一的最优先)
/// 3. 运行时自动生效;也可手动调用 Apply() 强制刷新
/// </summary>
[AddComponentMenu("UI/TMP Sprite Priority")]
[RequireComponent(typeof(TMP_Text))]
public class TMP_SpritePriority : MonoBehaviour
{
[Header("优先渲染的 SpriteAsset 列表(顺序即优先级,第一个最高)")]
[SerializeField]
private List<TMP_SpriteAsset> prioritySpriteAssets = new List<TMP_SpriteAsset>();
[Header("是否在 Awake 时自动应用")]
[SerializeField]
private bool applyOnAwake = true;
private TMP_Text _tmpText;
private void Awake()
{
_tmpText = GetComponent<TMP_Text>();
if (applyOnAwake)
Apply();
}
/// <summary>
/// 手动触发,将 SpriteAsset 插入 fallback 最前面,实现"Sprite 优先于 Font"渲染
/// </summary>
public void Apply()
{
if (_tmpText == null)
_tmpText = GetComponent<TMP_Text>();
if (_tmpText == null || prioritySpriteAssets == null || prioritySpriteAssets.Count == 0)
return;
// 取第一个作为 TMP_Text.spriteAsset(TMP 解析 <sprite> / 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<TMP_SpriteAsset>();
// 把列表[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} 个图片资源已置为最高优先级");
}
/// <summary>
/// 恢复到系统默认(清除手动设置的 spriteAsset,交回 TMP Settings 管理)
/// </summary>
public void Reset()
{
if (_tmpText == null) return;
_tmpText.spriteAsset = null; // null = 使用 TMP Settings 中的默认 SpriteAsset
_tmpText.SetAllDirty();
_tmpText.ForceMeshUpdate();
}
}