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

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.

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).

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:

void SetupNewAtlasTexture()
        {
            m_AtlasTextureIndex += 1;

            // Check size of atlas texture array
            if (m_AtlasTextures.Length == m_AtlasTextureIndex)
                Array.Resize(ref m_AtlasTextures, m_AtlasTextures.Length * 2);

            // Initialize new atlas texture
            m_AtlasTextures[m_AtlasTextureIndex] = new Texture2D(m_AtlasWidth, m_AtlasHeight, TextureFormat.Alpha8, false);
            FontEngine.ResetAtlasTexture(m_AtlasTextures[m_AtlasTextureIndex]);

            // Clear packing GlyphRects
            int packingModifier = ((GlyphRasterModes)m_AtlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP ? 0 : 1;
            m_FreeGlyphRects.Clear();
            m_FreeGlyphRects.Add(new GlyphRect(0, 0, m_AtlasWidth - packingModifier, m_AtlasHeight - packingModifier));
            m_UsedGlyphRects.Clear();

            #if UNITY_EDITOR
            // Add new texture as sub asset to font asset
            if (UnityEditor.EditorUtility.IsPersistent(this))
            {
                Texture2D tex = m_AtlasTextures[m_AtlasTextureIndex];
                // m_AtlasTexture below is null
                tex.name = m_AtlasTexture.name + " " + m_AtlasTextureIndex;

                UnityEditor.AssetDatabase.AddObjectToAsset(m_AtlasTextures[m_AtlasTextureIndex], this);
                TMP_EditorResourceManager.RegisterResourceForReimport(this);
            }
            #endif
        }

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.

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 :slight_smile:

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?

You can reset font assets by using the Context Menu Reset option as seen below.

6852182--798128--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.

4 Likes

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.

Resetting fixed the issue for me!

Resetting and not even remaking the font atlas is not fixing the issue for me
It appears to be happening when trying to dynamically add certain unicode characters.

Ex. :heart: and △ both exist in Noto Sans Symbols, but when generation of them is attempted, this error is thrown.

In fact the only character I’ve had success with that isn’t breaking the atlas is ✰ so far.
It at least appears to work in builds.