【Unity】Editor下批量修改UI Prefab字體

一般情況UI界面都是動態加載到場景,一鍵對UI Prefab批量修改字體,如果要修改字號、字體格式或者對齊方式等Text組件的其他操作,可以根據需求繼續擴展。

操作一:

在面板中選中需要修改Text組件的預設體,打開"MyTools/Change Font"工具下的"Change Font By Select"面板,選擇目標字體,"Change Selection Font"確認修改即可。

操作二:

替換字體,選擇被替換的字體,查找,然後指定目標字體,"Change Selection Font"確認修改即可。

或者"Change All Prefab Font"直接替換所有UI Prefab的字體,一鍵修改。

需要設置UI Prefab的路徑:private static string[] uiPrefabPaths = new string[] { "Assets/Resources/UIPrefab", "自定義路徑" };

附代碼: 

#if UNITY_EDITOR

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

namespace SimpleFrame.Tool
{

    public class ChangeFontByObjWindow : EditorWindow
    {
        [MenuItem("MyTools/Change Font/Change Font By Select")]
        public static void ShowWindow()
        {
            //彈出窗口
            EditorWindow.GetWindow(typeof(ChangeFontByObjWindow), false, "Change Font Window");
        }

        string showNotify;

        //目標字體、類型
        Font targetFont;

        List<GameObject> selectTextPrefabList = new List<GameObject>();
        GameObject newAddObj;

        void OnEnable()
        {
            GameObject[] tmpSelections = Selection.gameObjects;
            selectTextPrefabList.Clear();
            selectTextPrefabList.AddRange(tmpSelections);

            newAddObj = null;
            showNotify = "";
        }

        Vector2 scrollPosition = Vector2.zero;
        void OnGUI()
        {
            scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(position.width), GUILayout.Height(position.height));

            GUILayout.Space(10);
            GUILayout.Label("U Can Select GameObjects By Mouse In Hierachy And Project Then Open This Window");

            //選擇目標字體
            GUILayout.Space(10);
            GUILayout.Label("Target Font");
            targetFont = (Font)EditorGUILayout.ObjectField(targetFont, typeof(Font), true);
            ////選擇目標字號
            //GUILayout.Label("Target Font Size (if value < 0, will not change font size)");
            //targetFontSize = EditorGUILayout.IntField(targetFontSize);
            ////選擇目標字體類型
            //GUILayout.Label("Target FontStyle");
            //targetFontStyle = (FontStyle)EditorGUILayout.EnumPopup(targetFontStyle);

            //已選中GameObject列表
            GUILayout.Space(10);
            GUILayout.Label("Selection");
            if (selectTextPrefabList != null && selectTextPrefabList.Count > 0)
            {
                for (int i = 0; i < selectTextPrefabList.Count; i++)
                {
                    selectTextPrefabList[i] = EditorGUILayout.ObjectField(selectTextPrefabList[i], typeof(GameObject), true) as GameObject;
                }
            }
            else
                GUILayout.Label("None");

            //新添加到GameObject列表
            GUILayout.Space(10);
            GUILayout.Label("Add To Selection");
            newAddObj = EditorGUILayout.ObjectField(newAddObj, typeof(GameObject), true) as GameObject;
            if (newAddObj != null && !selectTextPrefabList.Contains(newAddObj))
            {
                if (GUILayout.Button("Add Obj"))
                {
                    for (int i = 0; i < selectTextPrefabList.Count; i++)
                    {
                        if (selectTextPrefabList[i] == null)
                        {
                            selectTextPrefabList[i] = newAddObj;
                            showNotify = "Add Obj To Select List";
                            return;
                        }
                    }
                    selectTextPrefabList.Add(newAddObj);
                    showNotify = "Add Obj To Select List";
                }
            }

            GUILayout.Space(10);
            if (GUILayout.Button("Change Selection Font"))
            {
                int count;
                ChangeFontTool.ChangeTextFontRecursion(selectTextPrefabList, targetFont, out count);
                ChangeFontTool.SaveAllPrefab(selectTextPrefabList);
                if (count < 0)
                    showNotify = "Change text font failed";
                else
                    showNotify = "Change text font success : " + count;
            }

            GUILayout.Space(10);
            //關閉彈窗
            if (GUILayout.Button("Close"))
            {
                this.Close();
            }

            GUILayout.Space(10);
            GUILayout.Label(showNotify);

            GUILayout.EndScrollView();
            //this.Repaint();
        }

        void OnDisable()
        {
            selectTextPrefabList.Clear();
            newAddObj = null;

            showNotify = "";
        }

    }

    // ---------

    public class ChangeFontByFontWindow : EditorWindow
    {
        [MenuItem("MyTools/Change Font/Change Font By Font")]
        public static void ShowWindow()
        {
            //彈出窗口
            EditorWindow.GetWindow(typeof(ChangeFontByFontWindow), false, "Change Font Window");
        }

        string showNotify;

        Font targetFont;
        Font searchFont;

        int uiPrefabCount;
        int allTextCount;

        List<GameObject> allPrefabRootList;
        List<GameObject> allPrefabTextList;
        List<GameObject> searchTextList = new List<GameObject>();

        private void OnEnable()
        {
            searchTextList.Clear();
            ChangeFontTool.GetAllTextPrefabs(out allPrefabRootList, out allPrefabTextList);
            uiPrefabCount = allPrefabRootList.Count;
            allTextCount = allPrefabTextList.Count;
            showNotify = "Find text component " + allTextCount + " from ui prefab " + uiPrefabCount;
        }

        Vector2 scrollPosition = Vector2.zero;
        private void OnGUI()
        {
            scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(position.width), GUILayout.Height(position.height));

            GUILayout.Space(10);
            GUILayout.Label("Find text component " + allTextCount + " from ui prefab " + uiPrefabCount);

            //選擇查找字體
            GUILayout.Space(10);
            GUILayout.Label("Search Font");
            searchFont = (Font)EditorGUILayout.ObjectField(searchFont, typeof(Font), true);

            //查找字體
            if (GUILayout.Button("Search"))
            {
                searchTextList.Clear();

                for (int i = 0; i < allPrefabTextList.Count; i++)
                {
                    Text tempText = allPrefabTextList[i].GetComponent<Text>();
                    if (tempText.font == searchFont)
                        searchTextList.Add(allPrefabTextList[i]);
                }
            }

            if (searchTextList.Count > 0)
            {
                for (int i = 0; i < searchTextList.Count; i++)
                {
                    searchTextList[i] = EditorGUILayout.ObjectField(searchTextList[i].gameObject, typeof(GameObject), true) as GameObject;
                }
            }
            else
                GUILayout.Label("None");

            //選擇目標字體
            GUILayout.Space(10);
            GUILayout.Label("Target Font");
            targetFont = (Font)EditorGUILayout.ObjectField(targetFont, typeof(Font), true);
            ////選擇目標字號
            //GUILayout.Label("Target Font Size (if value < 0, will not change font size)");
            //targetFontSize = EditorGUILayout.IntField(targetFontSize);
            ////選擇目標字體類型
            //GUILayout.Label("Target FontStyle");
            //targetFontStyle = (FontStyle)EditorGUILayout.EnumPopup(targetFontStyle);

            GUILayout.Space(20);
            if (GUILayout.Button("Change Selection Font"))
            {
                int count;
                ChangeFontTool.ChangeTextFont(searchTextList, targetFont, out count);
                ChangeFontTool.SaveAllPrefab(allPrefabRootList);
                if (count < 0)
                    showNotify = "Change text font failed";
                else
                    showNotify = "Change text font success : " + count;
            }
            GUILayout.Space(10);
            if (GUILayout.Button("Change All Prefab Font"))
            {
                int count;
                ChangeFontTool.ChangeTextFont(allPrefabTextList, targetFont, out count);
                ChangeFontTool.SaveAllPrefab(allPrefabRootList);
                if (count < 0)
                    showNotify = "Change text font failed";
                else
                    showNotify = "Change text font success : " + count;
            }

            GUILayout.Space(20);
            if (GUILayout.Button("Refresh"))
            {
                searchTextList.Clear();
                ChangeFontTool.GetAllTextPrefabs(out allPrefabRootList, out allPrefabTextList);
                uiPrefabCount = allPrefabRootList.Count;
                allTextCount = allPrefabTextList.Count;
                showNotify = "Find text component " + allTextCount + " from ui prefab " + uiPrefabCount;
            }

            GUILayout.Space(10);
            if (GUILayout.Button("Close"))
            {
                this.Close();
            }

            GUILayout.Space(10);
            GUILayout.Label(showNotify);

            GUILayout.EndScrollView();
            //this.Repaint();
        }

        private void OnDisable()
        {
            allPrefabRootList.Clear();
            allPrefabTextList.Clear();
            searchTextList.Clear();

            showNotify = "";
        }

    }

    public class ChangeFontTool
    {
        private static string[] uiPrefabPaths = new string[] { "Assets/Resources/UIPrefab" };

        public static void GetAllTextPrefabs(out List<GameObject> allPrefabRootList, out List<GameObject> allPrefabTextList)
        {
            allPrefabRootList = new List<GameObject>();
            allPrefabTextList = new List<GameObject>();

            //獲取Project所有Text組件
            //獲取Asset文件夾下所有Prefab的GUID
            string[] ids = AssetDatabase.FindAssets("t:Prefab", uiPrefabPaths);
            string tmpPath;
            for (int i = 0; i < ids.Length; i++)
            {
                //根據GUID獲取路徑
                tmpPath = AssetDatabase.GUIDToAssetPath(ids[i]);
                if (!string.IsNullOrEmpty(tmpPath))
                {
                    //根據路徑獲取Prefab(GameObject)
                    GameObject prefab = AssetDatabase.LoadAssetAtPath(tmpPath, typeof(GameObject)) as GameObject;
                    if (prefab != null)
                    {
                        allPrefabRootList.Add(prefab);

                        GetAllTextFromChildren(prefab, ref allPrefabTextList);
                    }
                }
            }
        }

        private static void GetAllTextFromChildren(GameObject target, ref List<GameObject> textList)
        {
            if (target == null)
                return;

            Text tmpText = target.GetComponent<Text>();
            if (tmpText != null)
                textList.Add(target);

            if (target.transform.childCount > 0)
            {
                for (int i = 0; i < target.transform.childCount; i++)
                {
                    GetAllTextFromChildren(target.transform.GetChild(i).gameObject, ref textList);
                }
            }
        }

        public static void ChangeTextFontRecursion(List<GameObject> textPrefabList, Font font, out int successCount)
        {
            if (textPrefabList == null || textPrefabList.Count == 0 || font == null)
            {
                successCount = -1;
                return;
            }
            successCount = 0;
            for (int i = 0; i < textPrefabList.Count; i++)
            {
                if (textPrefabList[i] != null)
                {
                    ChangeTextFontRecursion(textPrefabList[i].gameObject, font, ref successCount);
                }
            }
        }

        private static void ChangeTextFontRecursion(GameObject textPrefab, Font font, ref int successCount)
        {
            if (textPrefab == null)
                return;

            Text tempText = textPrefab.GetComponent<Text>();
            if (tempText != null)
            {
                tempText.font = font;
                successCount++;
            }

            if (textPrefab.transform.childCount > 0)
            {
                for (int i = 0; i < textPrefab.transform.childCount; i++)
                {
                    ChangeTextFontRecursion(textPrefab.transform.GetChild(i).gameObject, font, ref successCount);
                }
            }
        }

        public static void ChangeTextFont(List<GameObject> textList, Font font, out int successCount)
        {
            if (textList == null || textList.Count == 0 || font == null)
            {
                successCount = -1;
                return;
            }
            successCount = 0;
            for (int i = 0; i < textList.Count; i++)
            {
                if (textList[i] == null)
                    continue;
                Text tempText = textList[i].GetComponent<Text>();
                if (tempText == null)
                    continue;

                tempText.font = font;

                //tmpText.fontStyle = fontStyle;,
                //if (fontSize >= 0)
                //    tmpText.fontSize = fontSize;

                successCount++;
            }
        }

        public static void SaveAllPrefab(List<GameObject> allPrefabRootList)
        {
            for (int i = 0; i < allPrefabRootList.Count; i++)
            {
                PrefabUtility.SavePrefabAsset(allPrefabRootList[i]);
            }
            AssetDatabase.SaveAssets();
            //EditorUtility.SetDirty(textList[i]);
        }
    }

}
#endif

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章