using System; using System.Collections.Generic; using UnityEngine; namespace UnityEngine.UI { // 全局记录使用了某个Font字体的所有Text,当这个Font的GlyphAtlas大小改变的时候通知这些Text重建mesh(更新UV) // 因为GlyphAtlas大小改变了,原先的UV已经不对了 public static class FontUpdateTracker { static Dictionary> m_Tracked = new Dictionary>(); public static void TrackText(Text t) { if (t.font == null) return; HashSet exists; m_Tracked.TryGetValue(t.font, out exists); if (exists == null) { // font texture重新生成的时候会调这个回调,然后需要Text组件重建mesh的UV数据,因为原先的fontGlyph里的UV已经不准了 // https://docs.unity3d.com/ScriptReference/Font-textureRebuilt.html // The textureRebuilt event is global for all fonts, so we add our delegate the first time we register *any* Text if (m_Tracked.Count == 0) Font.textureRebuilt += RebuildForFont; exists = new HashSet(); m_Tracked.Add(t.font, exists); } if (!exists.Contains(t)) exists.Add(t); } private static void RebuildForFont(Font f) { HashSet texts; m_Tracked.TryGetValue(f, out texts); if (texts == null) return; foreach (var text in texts) text.FontTextureChanged(); } public static void UntrackText(Text t) { if (t.font == null) return; HashSet texts; m_Tracked.TryGetValue(t.font, out texts); if (texts == null) return; texts.Remove(t); if (texts.Count == 0) { m_Tracked.Remove(t.font); // There is a global textureRebuilt event for all fonts, so once the last Text reference goes away, remove our delegate if (m_Tracked.Count == 0) Font.textureRebuilt -= RebuildForFont; } } } }