Variable Fonts in Unity: Any Weight and Width From One File

Last reviewed

Short answer

A variable font holds a continuous range of styles in one file, along axes such as weight, width and slant. TextMesh Pro and UI Toolkit do not expose those axes, so projects ship a separate font asset, and atlas, for every weight they use.

UniText reads the axes directly: any weight, width, slant, italic or optical size can be set per font, per range with <var>, or animated, from one font file.

The usual options

Variable fonts arrived with OpenType 1.8 in 2016: one file holds a family's faces and allows continuous variation along its axes. Unity's text systems have not adopted them.

  • TextMesh Pro. Its Font Weights table takes a separate font asset for each weight and otherwise fakes bold by thickening the distance field. A variable font file imports as its default instance only. The request to add variable font support has been open since 2020, and a recent issue fix makes the Font Asset Creator say that variable fonts are not supported instead of crashing.
  • UI Toolkit. The TextCore Font Asset Creator rejects variable fonts, and USS has no font-weight or font-variation-settings; text styles are normal, bold and italic.
  • Exporting static instances. fontTools' instancer can cut a variable font into static fonts, one per weight or width. Each then becomes its own font asset with its own atlas, and weights in between are not available.

Variable fonts in UniText

One variable font with its weight axis driven live across the whole 100–900 range.
  • Every registered axis. Weight (wght), width (wdth), italic (ital), slant (slnt) and optical size (opsz) can be set to any point in the font's design space.
  • Defaults per font. Axis defaults are set on the font asset. A font variant borrows the bytes of another font and pins its own axis values, so a “Semibold Condensed” preset costs no second copy of the file.
  • Per range. <var=700> sets weight 700, <var=700,80> adds width 80, <var=150%> and <var=+200> are relative to the default, and <b=700> asks for a real weight before synthesizing one.
  • Animated. Axis values are style parameters like any other, so the timeline sequencer, an Animator or code can animate weight or width smoothly.
  • System fonts too. When the operating system's font is variable, a requested weight such as 700 selects that instance of it.
text
Regular, <var=600>semibold</var>, <var=800,75>heavy and condensed</var>, <var=~,~,~,-12>slanted</var>.

Questions

Does every weight get its own atlas?

Each distinct design-space point rasterizes its own glyphs, and the variation cache is memory-aware. Points that are not displayed cost nothing.

Which fonts are variable?

A variable font lists its axes in its fvar table. UniText shows them in the font asset's Variable Font Axes section, so importing the file tells you which axes it has.

Check it in your project

Run the browser demo, follow the setup guide, or compare the free version with the licenses.

Related problems