why

In games developed in Unity, avoid the Resources folder and use the AssetBundle instead, but the TextMesh Pro component comes with the Resources folder, and if the AssetBundle resource references it, So TextMesh Pro is going to be called AssetBundle, which makes it redundant. However, if you change the name of TextMesh Pro’s Resources folder, TMP_Settings will fail to read and the font will not display at all.

Analysis of the

The TMP_Settings class is a singleton. When used initially, it will go to the Resources folder to read the resource configuration.

    public static TMP_Settings instance
    {
      get
      {
        if ((UnityEngine.Object) TMP_Settings.s_Instance == (UnityEngine.Object) null)
          TMP_Settings.s_Instance = UnityEngine.Resources.Load<TMP_Settings>("TMP Settings");
        returnTMP_Settings.s_Instance; }}Copy the code

There is no interface to assign tmp_settings. s_Instance, so it fails to read the default font later.

To solve

Since no interface can be assigned directly, the performance of the lost point is assigned using reflection, which is negligible because it only needs to be assigned once. Rename the Resources folder to something else, and move the tmp_settings. asset file to the AssetBundle prefetch directory. Finally, after the game resource detection is completed, the following code is called:

    public class TMPHelper
    {
        public static void LoadSettings()
        {
            TMP_Settings settings = ResManager.LoadAsset<TMP_Settings>("Prefab/Configs/TMPPro/TMP_Settings.asset");
            var settingsType = settings.GetType();
            var settingsInstanceInfo = settingsType.GetField("s_Instance", BindingFlags.Static | BindingFlags.NonPublic);
            settingsInstanceInfo.SetValue(null, settings); }}Copy the code

In this case, the game will automatically assign tmp_settings. s_Instance, but the TextMesh Pro component will not be available in the editor, so we need to assign it in the editor and add the editor class as follows:

[InitializeOnLoad]
public class GameLauncher
{
    static GameLauncher()
    {
        LoadSettings();
    }

    public static void LoadSettings()
    {
        TMP_Settings settings = ResManagerEditor.LoadAssetEditor<TMP_Settings>("Prefab/Configs/TMPPro/TMP_Settings.asset");
        var settingsType = settings.GetType();
        var settingsInstanceInfo = settingsType.GetField("s_Instance", BindingFlags.Static | BindingFlags.NonPublic);
        settingsInstanceInfo.SetValue(null, settings); }}Copy the code

This way, assignment is automatically invoked whenever the editor is opened.

Other problems

If you change the Resources folder, the text parsing tag will fail, that is, the child font will not be embedded, and the following syntax will not be used:

Would you like <font="Impact SDF">a different font?</font> or just <font="NotoSans" material="NotoSans Outline">a different material?
Copy the code

Because when it comes to internal parsing, it goesResourcesUnder folderFonts & MaterialsThe folder searched for font, failed to display because it could not find it. All things considered, don’t write it this way.