TMP_SpriteAssetImporter.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using TMPro.EditorUtilities;
  6. using TMPro.SpriteAssetUtilities;
  7. namespace TMPro
  8. {
  9. public class TMP_SpriteAssetImporter : EditorWindow
  10. {
  11. // Create Sprite Asset Editor Window
  12. [MenuItem("Window/TextMeshPro/Sprite Importer", false, 2026)]
  13. public static void ShowFontAtlasCreatorWindow()
  14. {
  15. var window = GetWindow<TMP_SpriteAssetImporter>();
  16. window.titleContent = new GUIContent("Sprite Importer");
  17. window.Focus();
  18. }
  19. Texture2D m_SpriteAtlas;
  20. SpriteAssetImportFormats m_SpriteDataFormat = SpriteAssetImportFormats.TexturePacker;
  21. TextAsset m_JsonFile;
  22. string m_CreationFeedback;
  23. TMP_SpriteAsset m_SpriteAsset;
  24. List<TMP_Sprite> m_SpriteInfoList = new List<TMP_Sprite>();
  25. void OnEnable()
  26. {
  27. // Set Editor Window Size
  28. SetEditorWindowSize();
  29. }
  30. public void OnGUI()
  31. {
  32. DrawEditorPanel();
  33. }
  34. void DrawEditorPanel()
  35. {
  36. // label
  37. GUILayout.Label("Import Settings", EditorStyles.boldLabel);
  38. EditorGUI.BeginChangeCheck();
  39. // Sprite Texture Selection
  40. m_JsonFile = EditorGUILayout.ObjectField("Sprite Data Source", m_JsonFile, typeof(TextAsset), false) as TextAsset;
  41. m_SpriteDataFormat = (SpriteAssetImportFormats)EditorGUILayout.EnumPopup("Import Format", m_SpriteDataFormat);
  42. // Sprite Texture Selection
  43. m_SpriteAtlas = EditorGUILayout.ObjectField("Sprite Texture Atlas", m_SpriteAtlas, typeof(Texture2D), false) as Texture2D;
  44. if (EditorGUI.EndChangeCheck())
  45. {
  46. m_CreationFeedback = string.Empty;
  47. }
  48. GUILayout.Space(10);
  49. GUI.enabled = m_JsonFile != null && m_SpriteAtlas != null && m_SpriteDataFormat == SpriteAssetImportFormats.TexturePacker;
  50. // Create Sprite Asset
  51. if (GUILayout.Button("Create Sprite Asset"))
  52. {
  53. m_CreationFeedback = string.Empty;
  54. // Read json data file
  55. if (m_JsonFile != null && m_SpriteDataFormat == SpriteAssetImportFormats.TexturePacker)
  56. {
  57. TexturePacker.SpriteDataObject sprites = JsonUtility.FromJson<TexturePacker.SpriteDataObject>(m_JsonFile.text);
  58. if (sprites != null && sprites.frames != null && sprites.frames.Count > 0)
  59. {
  60. int spriteCount = sprites.frames.Count;
  61. // Update import results
  62. m_CreationFeedback = "<b>Import Results</b>\n--------------------\n";
  63. m_CreationFeedback += "<color=#C0ffff><b>" + spriteCount + "</b></color> Sprites were imported from file.";
  64. // Create sprite info list
  65. m_SpriteInfoList = CreateSpriteInfoList(sprites);
  66. }
  67. }
  68. }
  69. GUI.enabled = true;
  70. // Creation Feedback
  71. GUILayout.Space(5);
  72. GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60));
  73. {
  74. EditorGUILayout.LabelField(m_CreationFeedback, TMP_UIStyleManager.label);
  75. }
  76. GUILayout.EndVertical();
  77. GUILayout.Space(5);
  78. GUI.enabled = m_JsonFile != null && m_SpriteAtlas && m_SpriteInfoList != null && m_SpriteInfoList.Count > 0; // Enable Save Button if font_Atlas is not Null.
  79. if (GUILayout.Button("Save Sprite Asset") && m_JsonFile != null)
  80. {
  81. string filePath = EditorUtility.SaveFilePanel("Save Sprite Asset File", new FileInfo(AssetDatabase.GetAssetPath(m_JsonFile)).DirectoryName, m_JsonFile.name, "asset");
  82. if (filePath.Length == 0)
  83. return;
  84. SaveSpriteAsset(filePath);
  85. }
  86. GUI.enabled = true;
  87. }
  88. /// <summary>
  89. ///
  90. /// </summary>
  91. List<TMP_Sprite> CreateSpriteInfoList(TexturePacker.SpriteDataObject spriteDataObject)
  92. {
  93. List<TexturePacker.SpriteData> importedSprites = spriteDataObject.frames;
  94. List<TMP_Sprite> spriteInfoList = new List<TMP_Sprite>();
  95. for (int i = 0; i < importedSprites.Count; i++)
  96. {
  97. TMP_Sprite sprite = new TMP_Sprite();
  98. sprite.id = i;
  99. sprite.name = Path.GetFileNameWithoutExtension(importedSprites[i].filename) ?? "";
  100. sprite.hashCode = TMP_TextUtilities.GetSimpleHashCode(sprite.name);
  101. // Attempt to extract Unicode value from name
  102. int unicode;
  103. int indexOfSeperator = sprite.name.IndexOf('-');
  104. if (indexOfSeperator != -1)
  105. unicode = TMP_TextUtilities.StringHexToInt(sprite.name.Substring(indexOfSeperator + 1));
  106. else
  107. unicode = TMP_TextUtilities.StringHexToInt(sprite.name);
  108. sprite.unicode = unicode;
  109. sprite.x = importedSprites[i].frame.x;
  110. sprite.y = m_SpriteAtlas.height - (importedSprites[i].frame.y + importedSprites[i].frame.h);
  111. sprite.width = importedSprites[i].frame.w;
  112. sprite.height = importedSprites[i].frame.h;
  113. //Calculate sprite pivot position
  114. sprite.pivot = importedSprites[i].pivot;
  115. // Properties the can be modified
  116. sprite.xAdvance = sprite.width;
  117. sprite.scale = 1.0f;
  118. sprite.xOffset = 0 - (sprite.width * sprite.pivot.x);
  119. sprite.yOffset = sprite.height - (sprite.height * sprite.pivot.y);
  120. spriteInfoList.Add(sprite);
  121. }
  122. return spriteInfoList;
  123. }
  124. /// <summary>
  125. ///
  126. /// </summary>
  127. /// <param name="filePath"></param>
  128. void SaveSpriteAsset(string filePath)
  129. {
  130. filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath.
  131. string dataPath = Application.dataPath;
  132. if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1)
  133. {
  134. 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 + "\"");
  135. return;
  136. }
  137. string relativeAssetPath = filePath.Substring(dataPath.Length - 6);
  138. string dirName = Path.GetDirectoryName(relativeAssetPath);
  139. string fileName = Path.GetFileNameWithoutExtension(relativeAssetPath);
  140. string pathNoExt = dirName + "/" + fileName;
  141. // Create new Sprite Asset using this texture
  142. m_SpriteAsset = CreateInstance<TMP_SpriteAsset>();
  143. AssetDatabase.CreateAsset(m_SpriteAsset, pathNoExt + ".asset");
  144. // Compute the hash code for the sprite asset.
  145. m_SpriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(m_SpriteAsset.name);
  146. // Assign new Sprite Sheet texture to the Sprite Asset.
  147. m_SpriteAsset.spriteSheet = m_SpriteAtlas;
  148. m_SpriteAsset.spriteInfoList = m_SpriteInfoList;
  149. // Add new default material for sprite asset.
  150. AddDefaultMaterial(m_SpriteAsset);
  151. }
  152. /// <summary>
  153. /// Create and add new default material to sprite asset.
  154. /// </summary>
  155. /// <param name="spriteAsset"></param>
  156. static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset)
  157. {
  158. Shader shader = Shader.Find("TextMeshPro/Sprite");
  159. Material material = new Material(shader);
  160. material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet);
  161. spriteAsset.material = material;
  162. material.hideFlags = HideFlags.HideInHierarchy;
  163. AssetDatabase.AddObjectToAsset(material, spriteAsset);
  164. }
  165. /// <summary>
  166. /// Limits the minimum size of the editor window.
  167. /// </summary>
  168. void SetEditorWindowSize()
  169. {
  170. EditorWindow editorWindow = this;
  171. Vector2 currentWindowSize = editorWindow.minSize;
  172. editorWindow.minSize = new Vector2(Mathf.Max(230, currentWindowSize.x), Mathf.Max(300, currentWindowSize.y));
  173. }
  174. }
  175. }