Bold is broken with TextMeshPro text after upgrading from Unity 2021 to Unity 6

After updating our project to 6000.0.42f1 from 2021.3.45f1, any fonts that use weight-based (dilation) bold feature have some glyphs that just don’t work and in fact weirder still, falls-back to other fonts!

Here you can see what the normal font looks like:
Screenshot 2025-03-19 at 5.59.49 PM

…Then when we enable the [B] (bold) button, the font renders like the this:
Screenshot 2025-03-19 at 5.59.54 PM

The Bold Weight is set to 0.75 and there are no alternative weight fonts set in the Font Asset:

This happens with all my fonts, not just this particular asset. With this font:
Screenshot 2025-03-19 at 6.28.03 PM
You can see that turning on [B] bold causes it to render in many different random fonts!
Screenshot 2025-03-19 at 6.28.11 PM

Huh, this guy just reported something perhaps related:

I don’t think that’s the same problem. The bold weight glyphs use whatever font rendered bold glyphs recently, almost like they are cached.

For Unity folks, this bug was posted with an example scene: IN-97677

Did you re-strike the Font Assets? Perhaps something about the SDF gradient values used in the previous version are no longer valid in this version…

I’m not sure what you mean by re-strike. We use Static Font Atlases. I tried regenerating the font atlases using the Font Asset Generator and the bug still exists. I noticed that in Unity 6, the otf/ttf font files seem to have their own texture and material as well as simple font atlas settings. I have to mark those files as “include font data” in order to even regenerate my “old” font atlases.

^ ^ That’s what I meant. Nevermind! :slight_smile:

I also tried it with a dynamic font with multiple atlases and the result was the same with bold enabled.

Same here. Unchecking bold option in TextMesh Pro UGUI Text seems to fix. But it is a bug anyway as this behavior doesn’t happens before upgrading the project to Unity 6.

Just chiming in, my project is also experiencing this issue in Unity 6000.0.41. Tried blowing away library folder, installing text mesh pro package from the git repo, rebuilding texture atlas, various TMP Font assets and familys. When turning bold on its like the texture atlas is missing certain characters like lower case l c t s. I verified the characters are showing in the generated texture atlas image and not showing in the missing hexadecimal character values. Tried various character sets like ASCII, ASCII Extended, Unicode, etc. Also noticing an issue with outlines on random letters. The outline value seems to fluctuate on certain characters based off the padding value in the font asset creator. I can provide much more information if needed.

They replied to my bug report saying that it should be fixed in package update 3.2.0-pre.12, and Unity 6000.0.43f1 just released with the same fix:

  • TextMeshPro: Fixed additional cases of incorrect character caching handling when font styles and weights are used with fallback font assets and multiple text objects present in the same scene. (UUM-97348)

I’m going to grab it and will confirm here…stay tuned.

I can confirm that the bug is fixed in Unity 6000.0.43f1

Bug was indeed fixed in 6000.0.43. Thanks!

This issue is still affecting my project in Unity 6000.1.3f1, but not as the OP mentioned. In my case, if you apply bold or any style to a text using a font different from the default font, the default font gets rendered instead.

For example:

Here only Lorem (no style) and Dolor (itallic) are rendered with the font I assigned in the TMP component. The others are using the default font.

It was supposed to only render the font assigned to the TMP component.

I’ve created a repro project and shared with the Bug Reporting platform, and they’ve added it to the issue tracker: UUM-107331.

Still happening in 6000.0.47 and 6000.1.4. I have the sprite asset used instead of the font itself. The only workaround is to setup overrides for bold and italic in the font asset. This is a problem because if you don’t really have a bold font asset to place there, the font won’t be bold anymore.

Let me say that this but is ridiculous and unacceptable. It’s breaking for a release. Fonts are a basic feature that can’t be this broken.

This is absolutely still broken. I’m on 6000.0.41f1.

This issue still exists in Unity 6000.0.49f1, and untoggling B(old) in TextMeshProText component seems to fix that, but unluckily, it’s a workaround instead of an actual fix. I can’t imagine browsing all prefabs using this component to do that.

I am currently working on this issue but still trying to find a good solution that would work for all.

Let’s consider the following font asset setup:

  • Primary static font asset that contains the letter “A”
    – Static bold version font asset assigned as bold font weight that also contains the letter “A”
    ** Dynamic font asset using same font assigned as local fallback
    *** Dynamic bold version of same font assigned as bold font weight

If we were to type “AB” in the Text Input using the above setup we would get the following output where the A is coming from the primary and B from the dynamic fallback.

If we were to select the Font Style Bold, we would get the following where the A is coming from the static bold font asset assigned as bold font weight on the primary but the B would be fake bold although our dynamic fallback has a dynamic font asset assign for bold font weight.

At some point, the above behavior was reported where the expectation was that we would end up using the true bold font weight and not synthesized bold.

Note: Light yellow indicates the character is coming from the primary. Darker yellow indicates it is coming from the local dynamic fallback. Light blue is font asset assigned to primary as bold font weight and darker blue, the font asset assigned to the dynamic fallback’s bold font weight.

Now, in the new version of TMP using the same setup and text, we get the following where we can see that we end up using the correct bold even if the character comes from the local dynamic fallback.

In this same version, we would get the same expected results even if the primary was a static empty font asset that contains a combination of local static and dynamic fallbacks with various font weights assigned as seen below.

In the above, the color coding remains the same but purple is using a true italic font asset and green a true italic bold font asset.

Up until this point, we should be getting the expected results for all.

Here is where this breaks with respect to this newly reported issue…

In this search for the correct font style and weight, we look at the primary → its potential assigned font style and weights → local fallbacks and their potential assign font styles and weights but eventually get to the global fallbacks and default font asset where in this case we end up using the font assets assigned to the default font asset. We would get the same result if that font asset along with potential fallbacks and font styles and weights were assigned to the global fallbacks.

So the question here is when do we give up and decide to fake bold and italic?

We could limit the search to just the primary and local fallbacks which would produce the same results as described above but because this would ignore the global and default, we would end up faking the font style based on the setup provided in this report. In theory this would resolve the issue but …

What if a user is using a combination of static, dynamic and assigned font weights and styles in the Global fallbacks?

Over the years, I have seen projects using both local and global fallbacks to handle localization. Using local fallbacks works well for most cases with the exception of when you are using multiple fonts for Latin text but a common one for localization where you dynamically re-order those fallbacks based on locale. Yeah… complex setup but I run into that a lot.

In the above scenario, using the global fallbacks makes it easier as only one list of fallbacks need to be re-ordered as opposed to now having to re-order that for each primary. Still doable but getting more complex.

Limiting the search to exclude local sprite asset, Global fallbacks and default font assets like I said before would resolve this issue while providing most of the newly added flexibility in setup but ideally, I would love to find a way to do it all.

The purpose of my post is to lay this out to get thoughts and ideas as two or more brains are better than just one :slight_smile:

Thoughts?

P.S. The above would resolve the initial report from @tessellation (which should have been resolved previously) but all subsequent iterations / reports.

My first though was that I’d limit the search to primary font asset, its font weight table, its local fallback font assets and those local fallback font assets’ font weight tables (so basically your idea). However, if I have an Arabic font assigned as local fallback to a primary Latin font and the Arabic font has bold variant assigned to its weight table, then I could hit the same issue: bold text would use Arabic bold font instead of using fake bold of Latin font. In this scenario, I don’t think we can just say “use global fallback for Arabic font” because Latin fonts may use different Arabic fonts depending on their visual appearance. So I’d ideally want a solution that works in this scenario, as well.

How about looking at the TMP_FontAssets’ Source Font Files? We’d consider local or global fallbacks only if their Source Font Files match. If user uses dynamic font asset, they must assign Source Font File anyways. So what’s the harm in requiring the Font to be assigned to the static font asset’s Source Font File, as well (for this feature to work)?

May I ask which approach you used in the 6.0.56f1 fix?

I’ve submitted a new bug report from Unity 6000.0.59f2: