Search Unity

HOWTO: Load ttf font files at runtime

Discussion in 'UGUI & TextMesh Pro' started by petrapparent, May 20, 2020.

  1. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    I couldn't find any direct instructions on how to load ttf font files at runtime (and not OS specific) and there are some complex solutions out there. So I cobbled together a fairly simple set of instructions if anyone is interested

    0) Select Window-TextMeshPro->Import TMP Essential Resources.
    1) Make sure that you have the ttf font file path
    2) Here's the code to load the Font
    Font font = new Font (<path to ttf font file>);

    TMP_FontAsset font_asset = TMP_FontAsset.CreateFontAsset (font);
    3) Assign the font_asset to the TMP_Text.font property
    TMP_Text label;

    label.font = font_asset

    TheZombieKiller user pointed out that currently the CreateFontAsset method does not accept an array of bytes, which is very useful if you are loading font assets from the cloud.
    https://forum.unity.com/threads/exp...tasset-createfontasset-that-take-byte.683920/
     
    Stephan_B likes this.
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I will add a variant to be able to create a font asset using a byte array.
     
    chris_ngale and petrapparent like this.
  3. bug5532

    bug5532

    Joined:
    Aug 16, 2011
    Posts:
    307
    Did this ever happen?
     
    petrapparent likes this.
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    What is your use case for this?

    I am asking as I have changed incoming to add support for the new Dynamic OS Font Assets which will enable users to more easily use system fonts or if you do need to be able to create font assets from a byte array?
     
  5. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    The idea is store the TTFs in the cloud and then process them in real time. This circumvents two issues:
    a) the font is not installed on the target machine
    b) the font cannot be install on the target machine as the user doesn't have admin permission to do so

    Particularly useful for a webasm target
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The question is who manages this byte array? For instance, once the font asset has been created and font face loaded, we need that byte array to remain in memory otherwise, boom :mad:

    I could certainly cache the byte array on the font asset. Maybe that would be fine.

    This can most certainly make it into the next set of preview releases.
     
    petrapparent likes this.
  7. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    Thanks! That sounds like the best approach. You can't rely on the program to manage the byte array.
     
  8. xaldin-76

    xaldin-76

    Joined:
    Oct 1, 2016
    Posts:
    25
    Any updates about this? I would like to avoid asset bundles too, and to create a dynamic TMP_FontAsset from a downloaded/cached byte array, would this be possible now? (TMP v3.0.6 or 3.2.0-pre.1)
     
  9. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    See my reply in the other thread here.

    Would the ability to create a font asset from a file path work or do you need to be able to create it from a byte array?
     
    xaldin-76 likes this.
  10. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    Hey @Stephen_B any update on this? For me either file path or byte array would work, as long as it doesn't require the font to be installed the system. Thanks!
     
  11. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    At the top of this email thread I detail how to read a non-system installed font into Unity.

    Here is some more code:

    // Since I'm loading the font data from the cloud I get it as a raw data drop
    byte[] data = <raw data of the TTF>;

    // As we cannot create a font from a byte stream,
    // write the raw data to a file
    string filename = "my.ttf";
    System.IO.File.WriteAllBytes (filename, data);

    // Now load the font via the Font class from the file that was just created
    Font font = new Font (filename);

    // Create the new TMP font asset for use with TMP text, input, etc..
    TMP_FontAsset font_asset = TMP_FontAsset.CreateFontAsset (font);
     
    xaldin-76 likes this.
  12. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    Thanks for the suggestion! Unfortunately this doesn't work for me. I have a valid ttf at Application.PersistentDataPath. When I try to create a unity font with it I get

    Unable to load font face for [Roboto-Regular.ttf]. Make sure "Include Font Data" is enabled in the Font Import Settings.
    UnityEngine.Debug:LogWarning (object,UnityEngine.Object)


    I don't think I can change import options at runtime, but I could be wrong.
     
  13. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    Make sure you have the following installed the TMP Essential resources:
    Select Window-TextMeshPro->Import TMP Essential Resources

    Also ensure that you do a File.Exists check on your path to make sure the ttf is actually read/readable

    If Roboto-Regular.ttf is available somewhere I can try see if my existing setup does work with it. But basically every font I've tried so far, works.

    Also make sure your build settings have the following set:
    Screen Shot 2021-12-13 at 11.11.13 AM.png
     
  14. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    This was the trick! Despite the path not changing, for some reason wrapping the font creation in a File.Exists call makes it work. Perhaps this is just a file system race condition and checking for the file makes it available, since I'm writing those bytes to disk just before I create the unity font. Thanks for the help!
     
  15. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    Curiously which platform are you using (PC/MacOS/iOS/etc..)?
     
  16. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    I haven't tested this in a build yet, but this behavior is on windows editor. I'm targeting UWP.
     
  17. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I did add the ability to create font assets from file path. This will be included in the next preview release which will be preview 3. So as long as you can access the font file at this file path, you will be able to create the font asset.

    I expect to have it available within the next 7 - 10 days.
     
  18. petrapparent

    petrapparent

    Joined:
    Jun 6, 2011
    Posts:
    28
    Thanks, although the real want is to have a font created from a TTF byte array. I believe there is an unexposed API call that does just that. This will be better for licensing where you don't have exposed files lying around (mainly for webassembly)
     
    pajamajama likes this.
  19. MehmetFatihGezen

    MehmetFatihGezen

    Joined:
    Jun 15, 2022
    Posts:
    3
    Is there any update about this?
    Which version of Unity is available with this?
    Is it available for 2021 LTS versions or just for versions later than 2022?
     
  20. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    This functionality is part of version 3.2.0-pre.3 of the TMP package which was released a while back. This package works with Unity 2020.3 or newer.