1. 程式人生 > >Unity TextMeshPro 字型檔的自動生成

Unity TextMeshPro 字型檔的自動生成

原因

在 Unity 中使用 TextMeshPro 的文字解決方案,當要生成字型檔圖集時,需要通過外掛提供的 【Font Asset Creator】工具,但是每次都需要重新設定選項,如下所示:


解決

反編譯編輯器檢視其程式碼,照著其實現步驟再實現一遍,注意的是升級外掛的話,也要看下實現的程式碼是否需要改動。另外,自動處理多個字型的部分邏輯如下:

    public void Update()
    {
        if (this.isProcessing)
        {
            var progress = TMPro_FontPlugin.Check_RenderProgress();
            m_FontAssetInfos[m_CurGenerateIndex].genPercent = progress * 100;
            this.Repaint();
        }
        if (!this.isRenderingDone)
        {
            return;
        }
        this.isProcessing = false;
        this.isRenderingDone = false;
        this.UpdateRenderFeedbackWindow();
        foreach (var asset in m_FontAssetInfos[m_CurGenerateIndex].assets)
        {
            this.CreateFontTexture();
            Save_SDF_FontAsset(asset);
        }
        GenerateNext();
    }

    public void OnGUI()
    {
        GUI.enabled = !this.isProcessing;
        EditorGUI.indentLevel++;
        GUILayout.Label(" Font Word", EditorStyles.boldLabel);
        if (GUILayout.Button("生成字型檔文字", GUILayout.MinHeight(22f)))
        {
            TextMeshProFontTextGen.GenChineseText();
        }

        GUILayout.Space(10f);
        GUILayout.Label(" Font Asset", EditorStyles.boldLabel);
        if (GUILayout.Button("生成字型檔資產", GUILayout.MinHeight(22f)))
        {
            Generate();
        }

        GUILayout.Space(10f);
        GUILayout.Label(" Font List", EditorStyles.boldLabel);
        foreach (var info in m_FontAssetInfos)
        {
            EditorGUILayout.BeginHorizontal();
            info.toggle = EditorGUILayout.ToggleLeft(info.fontName, info.toggle);
            GUILayout.Space(10f);
            EditorGUILayout.LabelField(EditorGUIUtil.TempContent($"({info.genPercent}%)"));
            EditorGUILayout.EndHorizontal();

            EditorGUI.indentLevel++;
            EditorGUI.indentLevel++;
            foreach (var asset in info.assets)
            {
                EditorGUILayout.LabelField(EditorGUIUtil.TempContent(Path.GetFileNameWithoutExtension(asset)));
            }
            EditorGUI.indentLevel--;
            EditorGUI.indentLevel--;
        }
        EditorGUI.indentLevel--;
        GUI.enabled = true;
    }

    private void FindFonts()
    {
        string str1 = "t:Font";
        string[] fonts = AssetDatabase.FindAssets(str1, new[] { "Assets/TextMeshPro" });

        m_FontAssetInfos.Clear();
        foreach (var font in fonts)
        {
            FontAssetInfo info = new FontAssetInfo();
            info.fontPath = AssetDatabase.GUIDToAssetPath(font);
            info.fontName = Path.GetFileNameWithoutExtension(info.fontPath);
            info.fontObj = AssetDatabase.LoadAssetAtPath<Font>(info.fontPath);
            if (info.fontObj == null)
            {
                continue;
            }

            List<string> assetPaths = new List<string>();
            str1 = "t:TMP_FontAsset " + info.fontName + "_SDF";
            var assets = AssetDatabase.FindAssets(str1, new[] { "Assets/TextMeshPro/Resources/Fonts_Materials" });
            foreach (var asset in assets)
            {
                assetPaths.Add(AssetDatabase.GUIDToAssetPath(asset));
            }

            info.assets = assetPaths.ToArray();
            m_FontAssetInfos.Add(info);
        }
    }

    private void Generate()
    {
        m_CurGenerateIndex = -1;
        GenerateNext();
    }

    private void GenerateNext()
    {
        m_CurGenerateIndex++;
        if (m_CurGenerateIndex >= m_FontAssetInfos.Count)
        {
            EditorUtility.DisplayDialog("提示", "生成字型檔資產成功!", "OK");
            return;
        }

        var info = m_FontAssetInfos[m_CurGenerateIndex];
        if (!info.toggle)
        {
            GenerateNext();
            return;
        }

        font_TTF = info.fontObj;
        font_size = 22;
        font_atlas_width = 2048;
        font_atlas_height = 2048;
        if (string.IsNullOrEmpty(characterSequence))
        {
            var characterList = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/TextMeshPro/chinese_3500.txt");
            this.characterSequence = characterList.text;
        }
        DoCreate();
    }