Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

TextMesh Pro Update Sprite Assets button not saving changes

Discussion in 'UGUI & TextMesh Pro' started by CDGKen, Mar 16, 2021.

  1. CDGKen

    CDGKen

    Joined:
    Jun 28, 2019
    Posts:
    30
    Hi,

    I encountered a minor bug with TMP 2.1.4. If you change a Sprite Asset by clicking the 'Update Sprite Asset' button, the Sprite Asset will correctly update, however the editor doesn't recognize it as dirty and therefore does not save the changes once you close the project. The only way I could get it to recognize that the Sprite Asset was updated and for it to save was by manually changing a value on the Sprite Asset.

    Again, not the biggest thing since changing a value and changing it back isn't hard. Also, not sure if this matters but I had updated from 2.1.1 to 2.1.4 (I skipped the other two versions because I was having problems with them). Also, I'm using Unity 2019.4.17.

    Thanks,

    Kenny
     
    HunterAhlquist likes this.
  2. Raseru

    Raseru

    Joined:
    Oct 4, 2013
    Posts:
    79
    Yeah this is still an issue as of 3.0.6 TMP with Unity 2020.3.3f1
    What I have been doing is renaming the asset, generating a new one, then replacing the old one with the new one outside of Unity to maintain the connection.
    Your method is way better and a lot safer and glad I found it. Still, it would be nice to see this fixed.
     
  3. HunterAhlquist

    HunterAhlquist

    Joined:
    Oct 6, 2013
    Posts:
    91
    Same issue here, perhaps they didn't set the asset dirty, thus not saving changes on editor exit. I've done that before with my own custom asset types
     
  4. Raseru

    Raseru

    Joined:
    Oct 4, 2013
    Posts:
    79
    2021.3.9f1 with 3.0.6 TMP still not working. Doesn't seem like there's any interest to fix it so I looked into doing it myself via code

    Tried setting the asset dirty and it wasn't enough, I got it working though by doing essentially what the [Update Sprite Asset] button does, you can see here for an idea.

    Just add it here
    [SerializeField] private TMPro.TMP_SpriteAsset _mySpriteAsset;
    then pass it to this method
    Code (CSharp):
    1. internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset)
    2.     {
    3.         // Get a list of all the sprites contained in the texture referenced by the sprite asset.
    4.         // This only works if the texture is set to sprite mode.
    5.         string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet);
    6.         if (string.IsNullOrEmpty(filePath))
    7.             return;
    8.         // Get all the sprites defined in the sprite sheet texture referenced by this sprite asset.
    9.         Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).ToArray();
    10.         // Return if sprite sheet texture does not have any sprites defined in it.
    11.         if (sprites.Length == 0)
    12.         {
    13.             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);
    14.             return;
    15.         }
    16.         List<TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable;
    17.         // Find available glpyh indexes
    18.         uint[] existingGlyphIndexes = spriteGlyphTable.Select(x => x.index).ToArray();
    19.         List<uint> availableGlyphIndexes = new List<uint>();
    20.         uint lastGlyphIndex = existingGlyphIndexes.Length > 0 ? existingGlyphIndexes.Last() : 0;
    21.         int elementIndex = 0;
    22.         for (uint i = 0; i < lastGlyphIndex; i++)
    23.         {
    24.             uint existingGlyphIndex = existingGlyphIndexes[elementIndex];
    25.             if (i == existingGlyphIndex)
    26.                 elementIndex += 1;
    27.             else
    28.                 availableGlyphIndexes.Add(i);
    29.         }
    30.         // Iterate over sprites contained in the updated sprite sheet to identify new and / or modified sprites.
    31.         for (int i = 0; i < sprites.Length; i++)
    32.         {
    33.             Sprite sprite = sprites[i];
    34.             // Check if current sprites is already contained in the sprite glyph table of the sprite asset.
    35.             TMP_SpriteGlyph spriteGlyph = spriteGlyphTable.FirstOrDefault(x => x.sprite == sprite);
    36.             if (spriteGlyph != null)
    37.             {
    38.                 // update existing sprite glyph
    39.                 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)
    40.                     spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
    41.             }
    42.             else
    43.             {
    44.                 TMP_SpriteCharacter spriteCharacter;
    45.                 // Check if this sprite potentially exists under the same name in the sprite character table.
    46.                 if (spriteAsset.spriteCharacterTable != null && spriteAsset.spriteCharacterTable.Count > 0)
    47.                 {
    48.                     spriteCharacter = spriteAsset.spriteCharacterTable.FirstOrDefault(x => x.name == sprite.name);
    49.                     spriteGlyph = spriteCharacter != null ? spriteGlyphTable[(int)spriteCharacter.glyphIndex] : null;
    50.                     if (spriteGlyph != null)
    51.                     {
    52.                         // Update sprite reference and data
    53.                         spriteGlyph.sprite = sprite;
    54.                         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)
    55.                             spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
    56.                     }
    57.                 }
    58.                 // Add new Sprite Glyph to the table
    59.                 spriteGlyph = new TMP_SpriteGlyph();
    60.                 // Get available glyph index
    61.                 if (availableGlyphIndexes.Count > 0)
    62.                 {
    63.                     spriteGlyph.index = availableGlyphIndexes[0];
    64.                     availableGlyphIndexes.RemoveAt(0);
    65.                 }
    66.                 else
    67.                     spriteGlyph.index = (uint)spriteGlyphTable.Count;
    68.                 spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width);
    69.                 spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
    70.                 spriteGlyph.scale = 1.0f;
    71.                 spriteGlyph.sprite = sprite;
    72.                 spriteGlyphTable.Add(spriteGlyph);
    73.                 spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
    74.                 spriteCharacter.name = sprite.name;
    75.                 spriteCharacter.scale = 1.0f;
    76.                 spriteAsset.spriteCharacterTable.Add(spriteCharacter);
    77.             }
    78.         }
    79.         // Update Sprite Character Table to replace unicode 0x0 by 0xFFFE
    80.         for (int i = 0; i < spriteAsset.spriteCharacterTable.Count; i++)
    81.         {
    82.             TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[i];
    83.             if (spriteCharacter.unicode == 0)
    84.                 spriteCharacter.unicode = 0xFFFE;
    85.         }
    86.         // Sort glyph table by glyph index
    87.         spriteAsset.SortGlyphTable();
    88.         spriteAsset.UpdateLookupTables();
    89.         TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset);
    90.     }