Esempio n. 1
0
    /// <summary>
    /// 代码来源于TMPro.EditorUtilities.TMP_SpriteAssetMenu脚本中
    /// </summary>
    /// <param name="source"></param>
    /// <param name="spriteCharacterTable"></param>
    /// <param name="spriteGlyphTable"></param>
    private static void PopulateSpriteTables(Texture source, ref List <TMP_SpriteCharacter> spriteCharacterTable, ref List <TMP_SpriteGlyph> spriteGlyphTable)
    {
        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(0, spriteGlyph);
            spriteCharacter.name  = sprite.name;
            spriteCharacter.scale = 1.0f;

            spriteCharacterTable.Add(spriteCharacter);
        }
    }
        private 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);
            }
        }
Esempio n. 3
0
    /// <summary>
    /// 缓存图集数据
    /// </summary>
    private void CacheSpriteAssetData()
    {
        TMP_SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath <TMP_SpriteAsset>(SpriteAssetPath);

        if (spriteAsset != null)
        {
            cacheSpriteGlyphs = new List <TMP_SpriteGlyph>(spriteAsset.spriteGlyphTable.Count);
            for (int i = 0; i < spriteAsset.spriteGlyphTable.Count; i++)
            {
                TMP_SpriteGlyph spriteGlyph       = new TMP_SpriteGlyph();
                TMP_SpriteGlyph originSpriteGlyph = spriteAsset.spriteGlyphTable[i];
                spriteGlyph.sprite     = originSpriteGlyph.sprite;
                spriteGlyph.atlasIndex = originSpriteGlyph.atlasIndex;
                spriteGlyph.scale      = originSpriteGlyph.scale;
                spriteGlyph.index      = originSpriteGlyph.index;

                spriteGlyph.metrics = new GlyphMetrics(originSpriteGlyph.metrics.width,
                                                       originSpriteGlyph.metrics.height, originSpriteGlyph.metrics.horizontalBearingX,
                                                       originSpriteGlyph.metrics.horizontalBearingY, originSpriteGlyph.metrics.horizontalAdvance);

                spriteGlyph.glyphRect = new GlyphRect(originSpriteGlyph.glyphRect.x, originSpriteGlyph.glyphRect.y,
                                                      originSpriteGlyph.glyphRect.width, originSpriteGlyph.glyphRect.height);
                cacheSpriteGlyphs.Add(spriteGlyph);
            }

            //spriteCharacterTable
            cacheSpriteCharacters = new List <TMP_SpriteCharacter>(spriteAsset.spriteCharacterTable.Count);
            for (int i = 0; i < spriteAsset.spriteCharacterTable.Count; i++)
            {
                TMP_SpriteCharacter spriteCharacter       = new TMP_SpriteCharacter();
                TMP_SpriteCharacter originSpriteCharacter = spriteAsset.spriteCharacterTable[i];

                spriteCharacter.unicode    = originSpriteCharacter.unicode;
                spriteCharacter.glyphIndex = originSpriteCharacter.glyphIndex;
                spriteCharacter.scale      = originSpriteCharacter.scale;
                spriteCharacter.name       = originSpriteCharacter.name;
                spriteCharacter.glyph      = cacheSpriteGlyphs[i];

                cacheSpriteCharacters.Add(spriteCharacter);
            }
        }
    }
Esempio n. 4
0
    /// <summary>
    /// 更新图集数据
    /// </summary>
    private void ApplySpriteAssetData()
    {
        if (cacheSpriteGlyphs == null || cacheSpriteGlyphs.Count == 0 || cacheSpriteCharacters == null ||
            cacheSpriteCharacters.Count == 0)
        {
            Debug.LogError("无缓存数据");
        }

        //1.解析新的tpsheet
        string str = File.ReadAllText(arrangeIconAtlasTpsheetFilePath);

        string[] strArr = str.Split('\n');

        //以Name为key的GlyphRect数据
        Dictionary <string, GlyphRect> glyphRectDic = new Dictionary <string, GlyphRect>();

        foreach (var item in strArr)
        {
               
            if (item.StartsWith("#") || item.StartsWith(":") || string.IsNullOrEmpty(item) || item.StartsWith("\r"))
            {
                continue;
            }
            string[]  strArr2 = item.Split(';');
            int       x       = int.Parse(strArr2[1]);
            int       y       = int.Parse(strArr2[2]);
            int       w       = int.Parse(strArr2[3]);
            int       h       = int.Parse(strArr2[4]);
            GlyphRect rect    = new GlyphRect(x, y, w, h);
            glyphRectDic.Add(strArr2[0], rect);
        }

        //1.1获取新的数据,主要使用GlyphMetrics
        Texture texture = AssetDatabase.LoadAssetAtPath <Texture>(AtlasPngPath);
        List <TMP_SpriteCharacter> newSpriteCharacters = new List <TMP_SpriteCharacter>();
        List <TMP_SpriteGlyph>     newSpriteGlyphs     = new List <TMP_SpriteGlyph>();

        PopulateSpriteTables(texture, ref newSpriteCharacters, ref newSpriteGlyphs);

        //2.更新Cache
        //2.1 cacheSpriteGlyphs
        //2.2 cacheSpriteCharacters
        if (cacheSpriteGlyphs != null && cacheSpriteGlyphs.Count > 0)
        {
            //更新Cache的SpriteGlyph的Rect

            for (int i = 0; i < cacheSpriteGlyphs.Count; i++)
            {
                TMP_SpriteGlyph glyph      = cacheSpriteGlyphs[i];
                string          spriteName = cacheSpriteCharacters[(int)glyph.index].name;
                if (glyphRectDic.ContainsKey(spriteName))
                {
                    GlyphRect newRect = glyphRectDic[spriteName];
                    glyph.glyphRect = new GlyphRect(newRect.x, newRect.y, newRect.width, newRect.height);
                }
            }
        }

        foreach (KeyValuePair <string, GlyphRect> glyphRect in glyphRectDic)
        {
            TMP_SpriteCharacter findSpriteCharacter = cacheSpriteCharacters.Find(character => character.name == glyphRect.Key);
            TMP_SpriteCharacter newSpriteCharacter  = newSpriteCharacters.Find(character => character.name == glyphRect.Key);
            if (findSpriteCharacter == null)
            {
                //新增的Sprite

                TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
                spriteGlyph.sprite     = null;
                spriteGlyph.atlasIndex = 0;
                spriteGlyph.scale      = 1.0f;
                spriteGlyph.index      = (uint)cacheSpriteGlyphs.Count;

                GlyphMetrics metrics = newSpriteCharacter.glyph.metrics;
                spriteGlyph.metrics = new GlyphMetrics(metrics.width, metrics.height, metrics.horizontalBearingX,
                                                       metrics.horizontalBearingY, metrics.horizontalAdvance);

                spriteGlyph.glyphRect = new GlyphRect(glyphRect.Value.x, glyphRect.Value.y,
                                                      glyphRect.Value.width, glyphRect.Value.height);

                cacheSpriteGlyphs.Add(spriteGlyph);

                TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph);
                spriteCharacter.glyphIndex = (uint)cacheSpriteCharacters.Count;
                spriteCharacter.scale      = 1;
                spriteCharacter.name       = glyphRect.Key;

                cacheSpriteCharacters.Add(spriteCharacter);
            }
        }

        //3.cache写入SpriteAsset
        TMP_SpriteAsset spriteAsset            = AssetDatabase.LoadAssetAtPath <TMP_SpriteAsset>(SpriteAssetPath);
        FieldInfo       spriteCharacterTablePi = spriteAsset.GetType().GetField("m_SpriteCharacterTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteCharacterTablePi)
        {
            spriteCharacterTablePi.SetValue(spriteAsset, cacheSpriteCharacters);
        }
        FieldInfo spriteGlyphTablePi = spriteAsset.GetType().GetField("m_SpriteGlyphTable", BindingFlags.NonPublic | BindingFlags.Instance);

        if (null != spriteGlyphTablePi)
        {
            spriteGlyphTablePi.SetValue(spriteAsset, cacheSpriteGlyphs);
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
        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);
                    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);
        }
        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 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();

            List <TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable;

            // Finding available glyph indexes to insert new glyphs into.
            var         tempGlyphTable        = spriteGlyphTable.OrderBy(glyph => glyph.index).ToList();
            List <uint> availableGlyphIndexes = new List <uint>();

            int elementIndex = 0;

            for (uint i = 0; i < tempGlyphTable[tempGlyphTable.Count - 1].index; i++)
            {
                uint currentElementIndex = tempGlyphTable[elementIndex].index;

                if (i == currentElementIndex)
                {
                    elementIndex += 1;
                }
                else
                {
                    availableGlyphIndexes.Add(i);
                }
            }

            // Iterate over each of the sprites in the texture to try to match them to existing sprites in the sprite asset.
            for (int i = 0; i < sprites.Length; i++)
            {
                int id = sprites[i].GetInstanceID();

                int glyphIndex = spriteGlyphTable.FindIndex(item => item.sprite.GetInstanceID() == id);

                if (glyphIndex == -1)
                {
                    // Add new Sprite Glyph to the table
                    Sprite sprite = sprites[i];

                    TMP_SpriteGlyph 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);

                    TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph);
                    spriteCharacter.name  = sprite.name;
                    spriteCharacter.scale = 1.0f;

                    spriteAsset.spriteCharacterTable.Add(spriteCharacter);
                }
                else
                {
                    // Look for changes in existing Sprite Glyph
                    Sprite sprite = sprites[i];

                    TMP_SpriteGlyph spriteGlyph = spriteGlyphTable[glyphIndex];

                    // We only update changes to the sprite position / glyph rect.
                    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);
                    }
                }
            }

            // Sort glyph table by glyph index
            spriteAsset.SortGlyphTable();
            spriteAsset.UpdateLookupTables();
            TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset);
        }