暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TMP_SpriteAssetImporter.cs 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.TextCore;
  4. using UnityEditor;
  5. using System.IO;
  6. using System.Collections.Generic;
  7. using TMPro.EditorUtilities;
  8. using TMPro.SpriteAssetUtilities;
  9. namespace TMPro
  10. {
  11. public class TMP_SpriteAssetImporter : EditorWindow
  12. {
  13. // Create Sprite Asset Editor Window
  14. [MenuItem("Window/TextMeshPro/Sprite Importer", false, 2026)]
  15. public static void ShowFontAtlasCreatorWindow()
  16. {
  17. var window = GetWindow<TMP_SpriteAssetImporter>();
  18. window.titleContent = new GUIContent("Sprite Importer");
  19. window.Focus();
  20. }
  21. Texture2D m_SpriteAtlas;
  22. SpriteAssetImportFormats m_SpriteDataFormat = SpriteAssetImportFormats.TexturePackerJsonArray;
  23. TextAsset m_JsonFile;
  24. string m_CreationFeedback;
  25. TMP_SpriteAsset m_SpriteAsset;
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. void OnEnable()
  30. {
  31. // Set Editor Window Size
  32. SetEditorWindowSize();
  33. }
  34. /// <summary>
  35. ///
  36. /// </summary>
  37. public void OnGUI()
  38. {
  39. DrawEditorPanel();
  40. }
  41. /// <summary>
  42. ///
  43. /// </summary>
  44. private void OnDisable()
  45. {
  46. // Clean up sprite asset object that may have been created and not saved.
  47. if (m_SpriteAsset != null && !EditorUtility.IsPersistent(m_SpriteAsset))
  48. DestroyImmediate(m_SpriteAsset);
  49. }
  50. /// <summary>
  51. ///
  52. /// </summary>
  53. void DrawEditorPanel()
  54. {
  55. // label
  56. GUILayout.Label("Import Settings", EditorStyles.boldLabel);
  57. EditorGUI.BeginChangeCheck();
  58. // Sprite Texture Selection
  59. m_JsonFile = EditorGUILayout.ObjectField("Sprite Data Source", m_JsonFile, typeof(TextAsset), false) as TextAsset;
  60. m_SpriteDataFormat = (SpriteAssetImportFormats)EditorGUILayout.EnumPopup("Import Format", m_SpriteDataFormat);
  61. // Sprite Texture Selection
  62. m_SpriteAtlas = EditorGUILayout.ObjectField("Sprite Texture Atlas", m_SpriteAtlas, typeof(Texture2D), false) as Texture2D;
  63. if (EditorGUI.EndChangeCheck())
  64. {
  65. m_CreationFeedback = string.Empty;
  66. }
  67. GUILayout.Space(10);
  68. GUI.enabled = m_JsonFile != null && m_SpriteAtlas != null && m_SpriteDataFormat != SpriteAssetImportFormats.None;
  69. // Create Sprite Asset
  70. if (GUILayout.Button("Create Sprite Asset"))
  71. {
  72. m_CreationFeedback = string.Empty;
  73. // Clean up sprite asset object that may have been previously created.
  74. if (m_SpriteAsset != null && !EditorUtility.IsPersistent(m_SpriteAsset))
  75. DestroyImmediate(m_SpriteAsset);
  76. // Read json data file
  77. if (m_JsonFile != null)
  78. {
  79. switch (m_SpriteDataFormat)
  80. {
  81. case SpriteAssetImportFormats.TexturePackerJsonArray:
  82. TexturePacker_JsonArray.SpriteDataObject jsonData = null;
  83. try
  84. {
  85. jsonData = JsonUtility.FromJson<TexturePacker_JsonArray.SpriteDataObject>(m_JsonFile.text);
  86. }
  87. catch
  88. {
  89. m_CreationFeedback = "The Sprite Data Source file [" + m_JsonFile.name + "] appears to be invalid or incorrectly formatted.";
  90. }
  91. if (jsonData != null && jsonData.frames != null && jsonData.frames.Count > 0)
  92. {
  93. int spriteCount = jsonData.frames.Count;
  94. // Update import results
  95. m_CreationFeedback = "<b>Import Results</b>\n--------------------\n";
  96. m_CreationFeedback += "<color=#C0ffff><b>" + spriteCount + "</b></color> Sprites were imported from file.";
  97. // Create new Sprite Asset
  98. m_SpriteAsset = CreateInstance<TMP_SpriteAsset>();
  99. // Assign sprite sheet / atlas texture to sprite asset
  100. m_SpriteAsset.spriteSheet = m_SpriteAtlas;
  101. List<TMP_SpriteGlyph> spriteGlyphTable = new List<TMP_SpriteGlyph>();
  102. List<TMP_SpriteCharacter> spriteCharacterTable = new List<TMP_SpriteCharacter>();
  103. PopulateSpriteTables(jsonData, spriteCharacterTable, spriteGlyphTable);
  104. m_SpriteAsset.spriteCharacterTable = spriteCharacterTable;
  105. m_SpriteAsset.spriteGlyphTable = spriteGlyphTable;
  106. }
  107. break;
  108. }
  109. }
  110. }
  111. GUI.enabled = true;
  112. // Creation Feedback
  113. GUILayout.Space(5);
  114. GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60));
  115. {
  116. EditorGUILayout.TextArea(m_CreationFeedback, TMP_UIStyleManager.label);
  117. }
  118. GUILayout.EndVertical();
  119. GUILayout.Space(5);
  120. GUI.enabled = m_JsonFile != null && m_SpriteAtlas && m_SpriteAsset != null;
  121. if (GUILayout.Button("Save Sprite Asset") && m_JsonFile != null)
  122. {
  123. string filePath = EditorUtility.SaveFilePanel("Save Sprite Asset File", new FileInfo(AssetDatabase.GetAssetPath(m_JsonFile)).DirectoryName, m_JsonFile.name, "asset");
  124. if (filePath.Length == 0)
  125. return;
  126. SaveSpriteAsset(filePath);
  127. }
  128. GUI.enabled = true;
  129. }
  130. /// <summary>
  131. ///
  132. /// </summary>
  133. /// <param name="spriteDataObject"></param>
  134. /// <param name="spriteCharacterTable"></param>
  135. /// <param name="spriteGlyphTable"></param>
  136. private static void PopulateSpriteTables(TexturePacker_JsonArray.SpriteDataObject spriteDataObject, List<TMP_SpriteCharacter> spriteCharacterTable, List<TMP_SpriteGlyph> spriteGlyphTable)
  137. {
  138. List<TexturePacker_JsonArray.Frame> importedSprites = spriteDataObject.frames;
  139. float atlasHeight = spriteDataObject.meta.size.h;
  140. for (int i = 0; i < importedSprites.Count; i++)
  141. {
  142. TexturePacker_JsonArray.Frame spriteData = importedSprites[i];
  143. TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
  144. spriteGlyph.index = (uint)i;
  145. spriteGlyph.metrics = new GlyphMetrics((int)spriteData.frame.w, (int)spriteData.frame.h, -spriteData.frame.w * spriteData.pivot.x, spriteData.frame.h * spriteData.pivot.y, (int)spriteData.frame.w);
  146. spriteGlyph.glyphRect = new GlyphRect((int)spriteData.frame.x, (int)(atlasHeight - spriteData.frame.h - spriteData.frame.y), (int)spriteData.frame.w, (int)spriteData.frame.h);
  147. spriteGlyph.scale = 1.0f;
  148. spriteGlyphTable.Add(spriteGlyph);
  149. TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph);
  150. spriteCharacter.name = spriteData.filename.Split('.')[0];
  151. spriteCharacter.unicode = 0xFFFE;
  152. spriteCharacter.scale = 1.0f;
  153. spriteCharacterTable.Add(spriteCharacter);
  154. }
  155. }
  156. /// <summary>
  157. ///
  158. /// </summary>
  159. /// <param name="filePath"></param>
  160. void SaveSpriteAsset(string filePath)
  161. {
  162. filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath.
  163. string dataPath = Application.dataPath;
  164. if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1)
  165. {
  166. Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\"");
  167. return;
  168. }
  169. string relativeAssetPath = filePath.Substring(dataPath.Length - 6);
  170. string dirName = Path.GetDirectoryName(relativeAssetPath);
  171. string fileName = Path.GetFileNameWithoutExtension(relativeAssetPath);
  172. string pathNoExt = dirName + "/" + fileName;
  173. // Save Sprite Asset
  174. AssetDatabase.CreateAsset(m_SpriteAsset, pathNoExt + ".asset");
  175. // Set version number
  176. m_SpriteAsset.version = "1.1.0";
  177. // Compute the hash code for the sprite asset.
  178. m_SpriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(m_SpriteAsset.name);
  179. // Add new default material for sprite asset.
  180. AddDefaultMaterial(m_SpriteAsset);
  181. }
  182. /// <summary>
  183. /// Create and add new default material to sprite asset.
  184. /// </summary>
  185. /// <param name="spriteAsset"></param>
  186. static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset)
  187. {
  188. Shader shader = Shader.Find("TextMeshPro/Sprite");
  189. Material material = new Material(shader);
  190. material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet);
  191. spriteAsset.material = material;
  192. material.hideFlags = HideFlags.HideInHierarchy;
  193. AssetDatabase.AddObjectToAsset(material, spriteAsset);
  194. }
  195. /// <summary>
  196. /// Limits the minimum size of the editor window.
  197. /// </summary>
  198. void SetEditorWindowSize()
  199. {
  200. EditorWindow editorWindow = this;
  201. Vector2 currentWindowSize = editorWindow.minSize;
  202. editorWindow.minSize = new Vector2(Mathf.Max(230, currentWindowSize.x), Mathf.Max(300, currentWindowSize.y));
  203. }
  204. }
  205. }