123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- using UnityEngine;
- using UnityEngine.TextCore;
- using UnityEngine.U2D;
- using UnityEditor;
- using System.Linq;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
-
-
- namespace TMPro.EditorUtilities
- {
- public static class TMP_SpriteAssetMenu
- {
- // Add a Context Menu to the Sprite Asset Editor Panel to Create and Add a Default Material.
- [MenuItem("CONTEXT/TMP_SpriteAsset/Add Default Material", true, 2200)]
- static bool AddDefaultMaterialValidate(MenuCommand command)
- {
- return AssetDatabase.IsOpenForEdit(command.context);
- }
-
- [MenuItem("CONTEXT/TMP_SpriteAsset/Add Default Material", false, 2200)]
- static void AddDefaultMaterial(MenuCommand command)
- {
- TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context;
-
- // Make sure the sprite asset already contains a default material
- if (spriteAsset != null && spriteAsset.material == null)
- {
- // Add new default material for sprite asset.
- AddDefaultMaterial(spriteAsset);
- }
- }
-
- // Add a Context Menu to the Sprite Asset Editor Panel to update existing sprite assets.
- [MenuItem("CONTEXT/TMP_SpriteAsset/Update Sprite Asset", true, 2100)]
- static bool UpdateSpriteAssetValidate(MenuCommand command)
- {
- return AssetDatabase.IsOpenForEdit(command.context);
- }
-
- [MenuItem("CONTEXT/TMP_SpriteAsset/Update Sprite Asset", false, 2100)]
- static void UpdateSpriteAsset(MenuCommand command)
- {
- TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context;
-
- if (spriteAsset == null)
- return;
-
- UpdateSpriteAsset(spriteAsset);
- }
-
-
- internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset)
- {
- // Get a list of all the sprites contained in the texture referenced by the sprite asset.
- // This only works if the texture is set to sprite mode.
- string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet);
-
- if (string.IsNullOrEmpty(filePath))
- return;
-
- // Get all the sprites defined in the sprite sheet texture referenced by this sprite asset.
- Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).ToArray();
-
- // Return if sprite sheet texture does not have any sprites defined in it.
- if (sprites.Length == 0)
- {
- Debug.Log("Sprite Asset <color=#FFFF80>[" + spriteAsset.name + "]</color>'s atlas texture does not appear to have any sprites defined in it. Use the Unity Sprite Editor to define sprites for this texture.", spriteAsset.spriteSheet);
- return;
- }
-
- List<TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable;
-
- // Find available glpyh indexes
- uint[] existingGlyphIndexes = spriteGlyphTable.Select(x => x.index).ToArray();
- List<uint> availableGlyphIndexes = new List<uint>();
-
- uint lastGlyphIndex = existingGlyphIndexes.Length > 0 ? existingGlyphIndexes.Last() : 0;
- int elementIndex = 0;
- for (uint i = 0; i < lastGlyphIndex; i++)
- {
- uint existingGlyphIndex = existingGlyphIndexes[elementIndex];
-
- if (i == existingGlyphIndex)
- elementIndex += 1;
- else
- availableGlyphIndexes.Add(i);
- }
-
- // Iterate over sprites contained in the updated sprite sheet to identify new and / or modified sprites.
- for (int i = 0; i < sprites.Length; i++)
- {
- Sprite sprite = sprites[i];
-
- // Check if current sprites is already contained in the sprite glyph table of the sprite asset.
- TMP_SpriteGlyph spriteGlyph = spriteGlyphTable.FirstOrDefault(x => x.sprite == sprite);
-
- if (spriteGlyph != null)
- {
- // update existing sprite glyph
- if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height)
- spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
- }
- else
- {
- TMP_SpriteCharacter spriteCharacter;
-
- // Check if this sprite potentially exists under the same name in the sprite character table.
- if (spriteAsset.spriteCharacterTable != null && spriteAsset.spriteCharacterTable.Count > 0)
- {
- spriteCharacter = spriteAsset.spriteCharacterTable.FirstOrDefault(x => x.name == sprite.name);
- spriteGlyph = spriteCharacter != null ? spriteGlyphTable[(int)spriteCharacter.glyphIndex] : null;
-
- if (spriteGlyph != null)
- {
- // Update sprite reference and data
- spriteGlyph.sprite = sprite;
-
- if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height)
- spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
- }
- }
-
- // Add new Sprite Glyph to the table
- spriteGlyph = new TMP_SpriteGlyph();
-
- // Get available glyph index
- if (availableGlyphIndexes.Count > 0)
- {
- spriteGlyph.index = availableGlyphIndexes[0];
- availableGlyphIndexes.RemoveAt(0);
- }
- else
- spriteGlyph.index = (uint)spriteGlyphTable.Count;
-
- spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width);
- spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
- spriteGlyph.scale = 1.0f;
- spriteGlyph.sprite = sprite;
-
- spriteGlyphTable.Add(spriteGlyph);
-
- spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
-
- // Special handling for .notdef sprite name.
- string fileNameToLowerInvariant = sprite.name.ToLowerInvariant();
- if (fileNameToLowerInvariant == ".notdef" || fileNameToLowerInvariant == "notdef")
- {
- spriteCharacter.name = fileNameToLowerInvariant;
- spriteCharacter.unicode = 0;
- }
- else
- {
- spriteCharacter.unicode = 0xFFFE;
- if (!string.IsNullOrEmpty(sprite.name) && sprite.name.Length > 2 && sprite.name[0] == '0' && (sprite.name[1] == 'x' || sprite.name[1] == 'X'))
- {
- spriteCharacter.unicode = (uint)TMP_TextUtilities.StringHexToInt(sprite.name.Remove(0, 2));
- }
- spriteCharacter.name = sprite.name;
- }
-
- spriteCharacter.scale = 1.0f;
-
- spriteAsset.spriteCharacterTable.Add(spriteCharacter);
- }
- }
-
- // Update Sprite Character Table to replace unicode 0x0 by 0xFFFE
- for (int i = 0; i < spriteAsset.spriteCharacterTable.Count; i++)
- {
- TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[i];
- if (spriteCharacter.unicode == 0)
- spriteCharacter.unicode = 0xFFFE;
- }
-
- // Sort glyph table by glyph index
- spriteAsset.SortGlyphTable();
- spriteAsset.UpdateLookupTables();
- TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset);
- EditorUtility.SetDirty(spriteAsset);
-
- }
-
-
- [MenuItem("Assets/Create/TextMeshPro/Sprite Asset", false, 200)]
- static void CreateSpriteAsset()
- {
- Object[] targets = Selection.objects;
-
- if (targets == null)
- {
- Debug.LogWarning("A Sprite Texture must first be selected in order to create a Sprite Asset.");
- return;
- }
-
- // Make sure TMP Essential Resources have been imported in the user project.
- if (TMP_Settings.instance == null)
- {
- Debug.Log("Unable to create sprite asset. Please import the TMP Essential Resources.");
-
- // Show Window to Import TMP Essential Resources
- return;
- }
-
- for (int i = 0; i < targets.Length; i++)
- {
- Object target = targets[i];
-
- // Make sure the selection is a font file
- if (target == null || target.GetType() != typeof(Texture2D))
- {
- Debug.LogWarning("Selected Object [" + target.name + "] is not a Sprite Texture. A Sprite Texture must be selected in order to create a Sprite Asset.", target);
- continue;
- }
-
- CreateSpriteAssetFromSelectedObject(target);
- }
- }
-
-
- static void CreateSpriteAssetFromSelectedObject(Object target)
- {
- // Get the path to the selected asset.
- string filePathWithName = AssetDatabase.GetAssetPath(target);
- string fileNameWithExtension = Path.GetFileName(filePathWithName);
- string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName);
- string filePath = filePathWithName.Replace(fileNameWithExtension, "");
- string uniquePath = AssetDatabase.GenerateUniqueAssetPath(filePath + fileNameWithoutExtension + ".asset");
-
- // Create new Sprite Asset
- TMP_SpriteAsset spriteAsset = ScriptableObject.CreateInstance<TMP_SpriteAsset>();
- AssetDatabase.CreateAsset(spriteAsset, uniquePath);
-
- spriteAsset.version = "1.1.0";
-
- // Compute the hash code for the sprite asset.
- spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name);
-
- List<TMP_SpriteGlyph> spriteGlyphTable = new List<TMP_SpriteGlyph>();
- List<TMP_SpriteCharacter> spriteCharacterTable = new List<TMP_SpriteCharacter>();
-
- if (target.GetType() == typeof(Texture2D))
- {
- Texture2D sourceTex = target as Texture2D;
-
- // Assign new Sprite Sheet texture to the Sprite Asset.
- spriteAsset.spriteSheet = sourceTex;
-
- PopulateSpriteTables(sourceTex, ref spriteCharacterTable, ref spriteGlyphTable);
-
- spriteAsset.spriteCharacterTable = spriteCharacterTable;
- spriteAsset.spriteGlyphTable = spriteGlyphTable;
-
- // Add new default material for sprite asset.
- AddDefaultMaterial(spriteAsset);
- }
- else if (target.GetType() == typeof(SpriteAtlas))
- {
- //SpriteAtlas spriteAtlas = target as SpriteAtlas;
-
- //PopulateSpriteTables(spriteAtlas, ref spriteCharacterTable, ref spriteGlyphTable);
-
- //spriteAsset.spriteCharacterTable = spriteCharacterTable;
- //spriteAsset.spriteGlyphTable = spriteGlyphTable;
-
- //spriteAsset.spriteSheet = spriteGlyphTable[0].sprite.texture;
-
- //// Add new default material for sprite asset.
- //AddDefaultMaterial(spriteAsset);
- }
-
- // Update Lookup tables.
- spriteAsset.UpdateLookupTables();
-
- // Get the Sprites contained in the Sprite Sheet
- EditorUtility.SetDirty(spriteAsset);
-
- //spriteAsset.sprites = sprites;
-
- // Set source texture back to Not Readable.
- //texImporter.isReadable = false;
-
- AssetDatabase.SaveAssets();
-
- AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version.
-
- //AssetDatabase.Refresh();
- }
-
-
- static void PopulateSpriteTables(Texture source, ref List<TMP_SpriteCharacter> spriteCharacterTable, ref List<TMP_SpriteGlyph> spriteGlyphTable)
- {
- //Debug.Log("Creating new Sprite Asset.");
-
- string filePath = AssetDatabase.GetAssetPath(source);
-
- // Get all the Sprites sorted by Index
- Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray();
-
- for (int i = 0; i < sprites.Length; i++)
- {
- Sprite sprite = sprites[i];
-
- TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
- spriteGlyph.index = (uint)i;
- spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width);
- spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
- spriteGlyph.scale = 1.0f;
- spriteGlyph.sprite = sprite;
-
- spriteGlyphTable.Add(spriteGlyph);
-
- TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
-
- // Special handling for .notdef sprite name.
- string fileNameToLowerInvariant = sprite.name.ToLowerInvariant();
- if (fileNameToLowerInvariant == ".notdef" || fileNameToLowerInvariant == "notdef")
- {
- spriteCharacter.unicode = 0;
- spriteCharacter.name = fileNameToLowerInvariant;
- }
- else
- {
- if (!string.IsNullOrEmpty(sprite.name) && sprite.name.Length > 2 && sprite.name[0] == '0' && (sprite.name[1] == 'x' || sprite.name[1] == 'X'))
- {
- spriteCharacter.unicode = (uint)TMP_TextUtilities.StringHexToInt(sprite.name.Remove(0, 2));
- }
- spriteCharacter.name = sprite.name;
- }
-
- spriteCharacter.scale = 1.0f;
-
- spriteCharacterTable.Add(spriteCharacter);
- }
- }
-
-
- static void PopulateSpriteTables(SpriteAtlas spriteAtlas, ref List<TMP_SpriteCharacter> spriteCharacterTable, ref List<TMP_SpriteGlyph> spriteGlyphTable)
- {
- // Get number of sprites contained in the sprite atlas.
- int spriteCount = spriteAtlas.spriteCount;
- Sprite[] sprites = new Sprite[spriteCount];
-
- // Get all the sprites
- spriteAtlas.GetSprites(sprites);
-
- for (int i = 0; i < sprites.Length; i++)
- {
- Sprite sprite = sprites[i];
-
- TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
- spriteGlyph.index = (uint)i;
- spriteGlyph.metrics = new GlyphMetrics(sprite.textureRect.width, sprite.textureRect.height, -sprite.pivot.x, sprite.textureRect.height - sprite.pivot.y, sprite.textureRect.width);
- spriteGlyph.glyphRect = new GlyphRect(sprite.textureRect);
- spriteGlyph.scale = 1.0f;
- spriteGlyph.sprite = sprite;
-
- spriteGlyphTable.Add(spriteGlyph);
-
- TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
- spriteCharacter.name = sprite.name;
- spriteCharacter.scale = 1.0f;
-
- spriteCharacterTable.Add(spriteCharacter);
- }
- }
-
-
- /// <summary>
- /// Create and add new default material to sprite asset.
- /// </summary>
- /// <param name="spriteAsset"></param>
- static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset)
- {
- Shader shader = Shader.Find("TextMeshPro/Sprite");
- Material material = new Material(shader);
- material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet);
-
- spriteAsset.material = material;
- material.name = spriteAsset.name + " Material";
- AssetDatabase.AddObjectToAsset(material, spriteAsset);
- }
-
-
- // Update existing SpriteInfo
- static List<TMP_Sprite> UpdateSpriteInfo(TMP_SpriteAsset spriteAsset)
- {
- //Debug.Log("Updating Sprite Asset.");
-
- string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet);
-
- // Get all the Sprites sorted Left to Right / Top to Bottom
- Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray();
-
- for (int i = 0; i < sprites.Length; i++)
- {
- Sprite sprite = sprites[i];
-
- // Check if the sprite is already contained in the SpriteInfoList
- int index = -1;
- if (spriteAsset.spriteInfoList.Count > i && spriteAsset.spriteInfoList[i].sprite != null)
- index = spriteAsset.spriteInfoList.FindIndex(item => item.sprite.GetInstanceID() == sprite.GetInstanceID());
-
- // Use existing SpriteInfo if it already exists
- TMP_Sprite spriteInfo = index == -1 ? new TMP_Sprite() : spriteAsset.spriteInfoList[index];
-
- Rect spriteRect = sprite.rect;
- spriteInfo.x = spriteRect.x;
- spriteInfo.y = spriteRect.y;
- spriteInfo.width = spriteRect.width;
- spriteInfo.height = spriteRect.height;
-
- // Get Sprite Pivot
- Vector2 pivot = new Vector2(0 - (sprite.bounds.min.x) / (sprite.bounds.extents.x * 2), 0 - (sprite.bounds.min.y) / (sprite.bounds.extents.y * 2));
-
- // The position of the pivot influences the Offset position.
- spriteInfo.pivot = new Vector2(0 - pivot.x * spriteRect.width, spriteRect.height - pivot.y * spriteRect.height);
-
- if (index == -1)
- {
- // Find the next available index for this Sprite
- int[] ids = spriteAsset.spriteInfoList.Select(item => item.id).ToArray();
-
- int id = 0;
- for (int j = 0; j < ids.Length; j++ )
- {
- if (ids[0] != 0) break;
-
- if (j > 0 && (ids[j] - ids[j - 1]) > 1)
- {
- id = ids[j - 1] + 1;
- break;
- }
-
- id = j + 1;
- }
-
- spriteInfo.sprite = sprite;
- spriteInfo.name = sprite.name;
- spriteInfo.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteInfo.name);
- spriteInfo.id = id;
- spriteInfo.xAdvance = spriteRect.width;
- spriteInfo.scale = 1.0f;
-
- spriteInfo.xOffset = spriteInfo.pivot.x;
- spriteInfo.yOffset = spriteInfo.pivot.y;
-
- spriteAsset.spriteInfoList.Add(spriteInfo);
-
- // Sort the Sprites by ID
- spriteAsset.spriteInfoList = spriteAsset.spriteInfoList.OrderBy(s => s.id).ToList();
- }
- else
- {
- spriteAsset.spriteInfoList[index] = spriteInfo;
- }
- }
-
- return spriteAsset.spriteInfoList;
- }
- }
- }
|