Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TMP_EditorResourceManager.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.Rendering;
  4. using UnityEditor;
  5. using UnityEditor.TextCore.LowLevel;
  6. namespace TMPro
  7. {
  8. static class EditorEventCallbacks
  9. {
  10. [InitializeOnLoadMethod]
  11. internal static void InitializeFontAssetResourceChangeCallBacks()
  12. {
  13. TMP_FontAsset.RegisterResourceForUpdate += TMP_EditorResourceManager.RegisterResourceForUpdate;
  14. TMP_FontAsset.RegisterResourceForReimport += TMP_EditorResourceManager.RegisterResourceForReimport;
  15. TMP_FontAsset.OnFontAssetTextureChanged += TMP_EditorResourceManager.AddTextureToAsset;
  16. TMP_FontAsset.SetAtlasTextureIsReadable += FontEngineEditorUtilities.SetAtlasTextureIsReadable;
  17. TMP_FontAsset.GetSourceFontRef += TMP_EditorResourceManager.GetSourceFontRef;
  18. TMP_FontAsset.SetSourceFontGUID += TMP_EditorResourceManager.SetSourceFontGUID;
  19. // Callback to handle clearing dynamic font asset data when closing the Editor
  20. EditorApplication.quitting += () =>
  21. {
  22. // Find all font assets in the project
  23. string searchPattern = "t:TMP_FontAsset";
  24. string[] fontAssetGUIDs = AssetDatabase.FindAssets(searchPattern);
  25. for (int i = 0; i < fontAssetGUIDs.Length; i++)
  26. {
  27. string fontAssetPath = AssetDatabase.GUIDToAssetPath(fontAssetGUIDs[i]);
  28. TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(fontAssetPath);
  29. if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width != 0)
  30. {
  31. Debug.Log("Clearing [" + fontAsset.name + "] dynamic font asset data.");
  32. fontAsset.ClearCharacterAndGlyphTablesInternal();
  33. }
  34. }
  35. };
  36. }
  37. }
  38. internal class TMP_EditorResourceManager
  39. {
  40. private static TMP_EditorResourceManager s_Instance;
  41. private readonly List<Object> m_ObjectUpdateQueue = new List<Object>();
  42. private HashSet<int> m_ObjectUpdateQueueLookup = new HashSet<int>();
  43. private readonly List<Object> m_ObjectReImportQueue = new List<Object>();
  44. private HashSet<int> m_ObjectReImportQueueLookup = new HashSet<int>();
  45. private readonly List<TMP_FontAsset> m_FontAssetDefinitionRefreshQueue = new List<TMP_FontAsset>();
  46. private HashSet<int> m_FontAssetDefinitionRefreshQueueLookup = new HashSet<int>();
  47. /// <summary>
  48. /// Get a singleton instance of the manager.
  49. /// </summary>
  50. internal static TMP_EditorResourceManager instance
  51. {
  52. get
  53. {
  54. if (s_Instance == null)
  55. s_Instance = new TMP_EditorResourceManager();
  56. return s_Instance;
  57. }
  58. }
  59. /// <summary>
  60. /// Register to receive rendering callbacks.
  61. /// </summary>
  62. private TMP_EditorResourceManager()
  63. {
  64. // Register to the appropriate callback for the given render pipeline.
  65. if (RenderPipelineManager.currentPipeline == null)
  66. Camera.onPostRender += OnCameraPostRender;
  67. else
  68. {
  69. #if UNITY_2023_3_OR_NEWER
  70. RenderPipelineManager.endContextRendering += OnEndOfFrame;
  71. #else
  72. RenderPipelineManager.endFrameRendering += OnEndOfFrame;
  73. #endif
  74. }
  75. Canvas.willRenderCanvases += OnPreRenderCanvases;
  76. }
  77. void OnCameraPostRender(Camera cam)
  78. {
  79. // Exclude the PreRenderCamera
  80. if (cam.cameraType != CameraType.SceneView)
  81. return;
  82. DoPostRenderUpdates();
  83. }
  84. void OnPreRenderCanvases()
  85. {
  86. DoPreRenderUpdates();
  87. }
  88. #if UNITY_2023_3_OR_NEWER
  89. void OnEndOfFrame(ScriptableRenderContext renderContext, List<Camera> cameras)
  90. {
  91. DoPostRenderUpdates();
  92. }
  93. #else
  94. void OnEndOfFrame(ScriptableRenderContext renderContext, Camera[] cameras)
  95. {
  96. DoPostRenderUpdates();
  97. }
  98. #endif
  99. /// <summary>
  100. /// Register resource for re-import.
  101. /// </summary>
  102. /// <param name="obj"></param>
  103. internal static void RegisterResourceForReimport(Object obj)
  104. {
  105. // Return if referenced object is not a persistent asset
  106. if (!EditorUtility.IsPersistent(obj))
  107. return;
  108. instance.InternalRegisterResourceForReimport(obj);
  109. }
  110. private void InternalRegisterResourceForReimport(Object obj)
  111. {
  112. int id = obj.GetInstanceID();
  113. if (m_ObjectReImportQueueLookup.Contains(id))
  114. return;
  115. m_ObjectReImportQueueLookup.Add(id);
  116. m_ObjectReImportQueue.Add(obj);
  117. }
  118. /// <summary>
  119. /// Register resource to be updated.
  120. /// </summary>
  121. /// <param name="obj"></param>
  122. internal static void RegisterResourceForUpdate(Object obj)
  123. {
  124. // Return if referenced object is not a persistent asset
  125. if (!EditorUtility.IsPersistent(obj))
  126. return;
  127. instance.InternalRegisterResourceForUpdate(obj);
  128. }
  129. private void InternalRegisterResourceForUpdate(Object obj)
  130. {
  131. int id = obj.GetInstanceID();
  132. if (m_ObjectUpdateQueueLookup.Contains(id))
  133. return;
  134. m_ObjectUpdateQueueLookup.Add(id);
  135. m_ObjectUpdateQueue.Add(obj);
  136. }
  137. /// <summary>
  138. ///
  139. /// </summary>
  140. /// <param name="fontAsset"></param>
  141. internal static void RegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
  142. {
  143. instance.InternalRegisterFontAssetForDefinitionRefresh(fontAsset);
  144. }
  145. private void InternalRegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
  146. {
  147. int id = fontAsset.GetInstanceID();
  148. if (m_FontAssetDefinitionRefreshQueueLookup.Contains(id))
  149. return;
  150. m_FontAssetDefinitionRefreshQueueLookup.Add(id);
  151. m_FontAssetDefinitionRefreshQueue.Add(fontAsset);
  152. }
  153. /// <summary>
  154. /// Add texture as sub asset to the referenced object.
  155. /// </summary>
  156. /// <param name="tex">The texture to be added as sub object.</param>
  157. /// <param name="obj">The object to which this texture sub object will be added.</param>
  158. internal static void AddTextureToAsset(Texture tex, Object obj)
  159. {
  160. // Return if referenced object is not a persistent asset
  161. if (!EditorUtility.IsPersistent(obj))
  162. return;
  163. if (tex != null)
  164. AssetDatabase.AddObjectToAsset(tex, obj);
  165. RegisterResourceForReimport(obj);
  166. }
  167. /// <summary>
  168. ///
  169. /// </summary>
  170. /// <param name="guid"></param>
  171. /// <returns></returns>
  172. internal static Font GetSourceFontRef(string guid)
  173. {
  174. string path = AssetDatabase.GUIDToAssetPath(guid);
  175. return AssetDatabase.LoadAssetAtPath<Font>(path);
  176. }
  177. /// <summary>
  178. ///
  179. /// </summary>
  180. /// <param name="font"></param>
  181. /// <returns></returns>
  182. internal static string SetSourceFontGUID(Font font)
  183. {
  184. return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(font));
  185. }
  186. void DoPostRenderUpdates()
  187. {
  188. // Handle objects that need updating
  189. int objUpdateCount = m_ObjectUpdateQueue.Count;
  190. for (int i = 0; i < objUpdateCount; i++)
  191. {
  192. EditorUtilities.TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup = true;
  193. #if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
  194. UnityEditor.TextCore.Text.TextCorePropertyDrawerUtilities.s_RefreshGlyphProxyLookup = true;
  195. #endif
  196. Object obj = m_ObjectUpdateQueue[i];
  197. if (obj != null)
  198. {
  199. //EditorUtility.SetDirty(obj);
  200. }
  201. }
  202. if (objUpdateCount > 0)
  203. {
  204. //Debug.Log("Saving assets");
  205. //AssetDatabase.SaveAssets();
  206. m_ObjectUpdateQueue.Clear();
  207. m_ObjectUpdateQueueLookup.Clear();
  208. }
  209. // Handle objects that need re-importing
  210. int objReImportCount = m_ObjectReImportQueue.Count;
  211. for (int i = 0; i < objReImportCount; i++)
  212. {
  213. Object obj = m_ObjectReImportQueue[i];
  214. if (obj != null)
  215. {
  216. string assetPath = AssetDatabase.GetAssetPath(obj);
  217. // Exclude Assets not located in the project
  218. if (assetPath.StartsWith("Assets/", System.StringComparison.OrdinalIgnoreCase))
  219. AssetDatabase.ImportAsset(assetPath);
  220. }
  221. }
  222. if (objReImportCount > 0)
  223. {
  224. m_ObjectReImportQueue.Clear();
  225. m_ObjectReImportQueueLookup.Clear();
  226. }
  227. }
  228. void DoPreRenderUpdates()
  229. {
  230. // Handle Font Asset Definition Refresh
  231. for (int i = 0; i < m_FontAssetDefinitionRefreshQueue.Count; i++)
  232. {
  233. TMP_FontAsset fontAsset = m_FontAssetDefinitionRefreshQueue[i];
  234. if (fontAsset != null)
  235. {
  236. fontAsset.ReadFontAssetDefinition();
  237. TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
  238. }
  239. }
  240. if (m_FontAssetDefinitionRefreshQueue.Count > 0)
  241. {
  242. m_FontAssetDefinitionRefreshQueue.Clear();
  243. m_FontAssetDefinitionRefreshQueueLookup.Clear();
  244. }
  245. }
  246. }
  247. }