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.

Bug MissingReferenceException: The variable m_AtlasTextures of TMP_FontAsset doesn't exist anymore.

Discussion in 'UGUI & TextMesh Pro' started by ianhsieh, Feb 18, 2021.

  1. ianhsieh

    ianhsieh

    Joined:
    Mar 9, 2018
    Posts:
    6
    I'm using version 2.1.3 and recently bumped into this error when [multi atlas textures] option is toggled on my font asset. It looks like a UNITY_EDITOR type error when running into new characters and TMP_FontAsset.cs trying to dynamically generate a new atlas in runtime. Here's the stacktrace:

    --
    UnityEngine.Texture.get_width () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Graphics/Texture.bindings.cs:38)
    TMPro.TMP_FontAsset.TryAddCharacterInternal (System.UInt32 unicode, TMPro.TMP_Character& character) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMP_FontAsset.cs:2053)
    TMPro.TMP_FontAssetUtilities.GetCharacterFromFontAsset_Internal (System.UInt32 unicode, TMPro.TMP_FontAsset sourceFontAsset, System.Boolean includeFallbacks, TMPro.FontStyles fontStyle, TMPro.FontWeight fontWeight, System.Boolean& isAlternativeTypeface) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMP_FontAssetUtilities.cs:159)
    TMPro.TMP_FontAssetUtilities.GetCharacterFromFontAssets (System.UInt32 unicode, TMPro.TMP_FontAsset sourceFontAsset, System.Collections.Generic.List`1[T] fontAssets, System.Boolean includeFallbacks, TMPro.FontStyles fontStyle, TMPro.FontWeight fontWeight, System.Boolean& isAlternativeTypeface) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMP_FontAssetUtilities.cs:241)
    TMPro.TMP_Text.GetTextElement (System.UInt32 unicode, TMPro.TMP_FontAsset fontAsset, TMPro.FontStyles fontStyle, TMPro.FontWeight fontWeight, System.Boolean& isUsingAlternativeTypeface) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMP_Text.cs:7320)
    TMPro.TextMeshProUGUI.SetArraySizes (TMPro.TMP_Text+UnicodeChar[] unicodeChars) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMPro_UGUI_Private.cs:1190)
    TMPro.TMP_Text.GetPreferredValues (System.String text, System.Single width, System.Single height) (at Library/PackageCache/com.unity.textmeshpro@2.1.3/Scripts/Runtime/TMP_Text.cs:4901)
    --

    Please check if there's any exception here. Thanks for the help.
     
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    There should be a few post about this on the forum already.

    This issue is related to the atlas texture somehow not getting serialized while the glyph table did and still referencing an atlas index for a texture that is null.

    Thus far I have been unable to identify and reproduce the conditions that lead to a font asset to get into this state. If any change, you are able to reproduce this (corruption for the lack of better term) of a dynamic font asset please provide me with the steps or submit a bug report with project so I can fix this.

    In the meantime, resetting the dynamic font asset(s) via the Context Menu will resolve the issue with such font asset(s).
     
  3. ianhsieh

    ianhsieh

    Joined:
    Mar 9, 2018
    Posts:
    6
    Thanks for your quick response. Actually I found some posts about this issue before reporting. The reason I assumed this as a bug is that I found these codes in TMP_FontAsset.cs are probably causing this issue:

    Code (CSharp):
    1. void SetupNewAtlasTexture()
    2.         {
    3.             m_AtlasTextureIndex += 1;
    4.  
    5.             // Check size of atlas texture array
    6.             if (m_AtlasTextures.Length == m_AtlasTextureIndex)
    7.                 Array.Resize(ref m_AtlasTextures, m_AtlasTextures.Length * 2);
    8.  
    9.             // Initialize new atlas texture
    10.             m_AtlasTextures[m_AtlasTextureIndex] = new Texture2D(m_AtlasWidth, m_AtlasHeight, TextureFormat.Alpha8, false);
    11.             FontEngine.ResetAtlasTexture(m_AtlasTextures[m_AtlasTextureIndex]);
    12.  
    13.             // Clear packing GlyphRects
    14.             int packingModifier = ((GlyphRasterModes)m_AtlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1;
    15.             m_FreeGlyphRects.Clear();
    16.             m_FreeGlyphRects.Add(new GlyphRect(0, 0, m_AtlasWidth - packingModifier, m_AtlasHeight - packingModifier));
    17.             m_UsedGlyphRects.Clear();
    18.  
    19.             #if UNITY_EDITOR
    20.             // Add new texture as sub asset to font asset
    21.             if (UnityEditor.EditorUtility.IsPersistent(this))
    22.             {
    23.                 Texture2D tex = m_AtlasTextures[m_AtlasTextureIndex];
    24.                 // m_AtlasTexture below is null
    25.                 tex.name = m_AtlasTexture.name + " " + m_AtlasTextureIndex;
    26.  
    27.                 UnityEditor.AssetDatabase.AddObjectToAsset(m_AtlasTextures[m_AtlasTextureIndex], this);
    28.                 TMP_EditorResourceManager.RegisterResourceForReimport(this);
    29.             }
    30.             #endif
    31.         }
    The '#if UNITY_EDITOR' part will cause an exception prior to the stacktrace (Line 2053) above. The variable m_AtlasTexture' is null when assigning name to the texture, and 'AddObjectToAsset' is never executed. I tried replacing 'm_AtlasTexture' with 'm_AtlasTextures[0]' and the error never happened again.

    Not pretty sure about this whole thing. Hope it point to the right direction. Thanks for your time.
     
    Last edited: Feb 18, 2021
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Changes to dynamic font assets are only persistent in the Editor. As such, the addition of new characters and glyphs are made persistent whenever the asset is serialized. In the case of the textures, they need to be added as sub objects to the font asset in order to make them persistent.

    At runtime, new characters, glyphs and atlas textures will be created as needed but none of these changes are persistent.

    Now back to this issue, it is behaving as if the changes to the character and glyph tables are made persistent as some of these glyphs still reference an atlas index other than zero but for some reason, the atlas texture at such index was never serialized. Ie. part of the change to the font asset became persistent but not the textures.

    I don't know if this happens as a result of some crash or Unity being closed unexpectedly. Maybe something related to source control where the changes to the character and glyph table are restored but not the sub object child textures.

    Maybe it is a build issue or some build services related issue.

    Clearly something is causing the font assets to get into this funky state. The challenge is what is causing it.

    I could add code to detect when a glyph is point to an atlas index other than zero and when such texture is null but that would mask / hide the issue which would still be happening. Like the doctor said, I can give you a cream to make the rash go away but if the rash is cause by eating "strawberries", the rash will keep coming :)
     
  5. NinjaDuck24

    NinjaDuck24

    Joined:
    Nov 7, 2015
    Posts:
    3
    Hello, I'm also having the same issue. Only when falling back to a font that supports CJK, similar to the other forum post you mentioned.

    Please can you explain exactly how to reset the dynamic font asset?
     
  6. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    You can reset font assets by using the Context Menu Reset option as seen below.

    upload_2021-2-18_10-55-28.png

    This preserves the face info and setting but clears the character, glyph and font feature tables as well as reset the atlas textures back to size 0.
     
    KietTuan and dave_thrive like this.
  7. ianhsieh

    ianhsieh

    Joined:
    Mar 9, 2018
    Posts:
    6
    I see your point here. Really appreciate the explanation. We have found way to reproduce this 'funky state' you mentioned above. We'll do our best to provide a reproducible project ASAP.

    For someone who consistently bumped into this issue, we have a workaround to solve this issue. Just manually put some new characters into your font asset and update atlas texture to generate new one (due to last atlas texture is almost full with characters). The issue will only happen if we bump into characters not included in font asset AND editor tries to generate a new one in runtime.
     
  8. thiagolrosa

    thiagolrosa

    Joined:
    Feb 22, 2017
    Posts:
    53
    Resetting fixed the issue for me!