unity 批量修改场景内字体工具

记录一个批量修改场景内字体的工具脚本。

csharp 复制代码
using System.Linq;
using TMPro;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ChangeFont : EditorWindow
{
    private TMP_FontAsset selectedFont;
    private string directory = "Please Enter The Full Path";//相对于项目文件夹的路径 Assets/...

    //菜单项
    [MenuItem("Tools/Change Font")]
    private static void ShowWindow()
    {
        //获取或创建一个ChangeFont实例,并进行显示
        EditorWindow.GetWindow<ChangeFont>("Change Font");
    }

    //绘制编辑器窗口的界面
    private void OnGUI()
    {
        //提示
        EditorGUILayout.LabelField("Select Font:", EditorStyles.boldLabel);

        //显示一个下拉列表,让用户选择一个字体
        selectedFont = (TMP_FontAsset)EditorGUILayout.ObjectField(selectedFont, typeof(TMP_FontAsset), false);

        //添加一个按钮,点击按钮时更换所有字体
        if (GUILayout.Button("Apply All 3DFonts In Scene"))
        {
            if (selectedFont != null)
            {
                ChangeAll3DFonts(selectedFont);

                // 获取当前场景的路径
                string scenePath = SceneManager.GetActiveScene().path;

                // 保存当前场景
                EditorSceneManager.SaveScene(SceneManager.GetSceneByPath(scenePath));
                Debug.Log("Scene saved: " + scenePath);
            }
            else
            {
                Debug.LogWarning("Please select a font first!");
            }
        }
        if (GUILayout.Button("Apply All 2DFonts In Scene"))
        {
            if (selectedFont != null)
            {
                ChangeAll2DFonts(selectedFont);

                // 获取当前场景的路径
                string scenePath = SceneManager.GetActiveScene().path;

                // 保存当前场景
                EditorSceneManager.SaveScene(SceneManager.GetSceneByPath(scenePath));
                Debug.Log("Scene saved: " + scenePath);
            }
            else
            {
                Debug.LogWarning("Please select a font first!");
            }
        }

        EditorGUILayout.LabelField("");
        if (GUILayout.Button("Apply All Fonts In All Prefabs"))
        {
            if (selectedFont != null)
            {
                ChangeFontsInAllPrefabs(selectedFont);
            }
            else
            {
                Debug.LogWarning("Please select a font first!");
            }
        }

        EditorGUILayout.LabelField("");
        //输入文本框
        directory = EditorGUILayout.TextField("Specified Directory", directory);
        if (GUILayout.Button("Apply All Fonts In Prefabs In Directory"))
        {
            if (selectedFont != null)
            {
                if (directory != null && directory != "Please enter the full path")
                {
                    ChangeFontsInPrefabsInDirectory(selectedFont, directory);
                }
                else
                {
                    Debug.LogWarning("Please enter a directory!");
                }
            }
            else
            {
                Debug.LogWarning("Please select a font first!");
            }
        }
    }

    /// <summary>
    /// 更换场景中所有文本的字体
    /// </summary>
    /// <param name="font">选择的字体</param>
    private static void ChangeAll3DFonts(TMP_FontAsset font)
    {
        //得到场景中的所有TMP_Text,并更换TMP_Text的字体
        TextMeshPro[] allTexts = GameObject.FindObjectsOfType<TextMeshPro>(true);
        foreach (TextMeshPro text in allTexts)
        {
            text.font = font;
        }

        if (allTexts.Length > 0)
        {
            //用于刷新AssetDatabase的缓存和数据,使得最新的资源信息和项目状态能够在编辑器中正确显示和更新
            AssetDatabase.Refresh();
            Debug.Log("Changed all fonts in scene to: " + font.name);
        }
        else
        {
            Debug.Log("There are no fonts to change");
        }
    }

    private static void ChangeAll2DFonts(TMP_FontAsset font)
    {
        //得到场景中的所有TMP_Text,并更换TMP_Text的字体
        TextMeshProUGUI[] allTexts = GameObject.FindObjectsOfType<TextMeshProUGUI>(true);
        foreach (TextMeshProUGUI text in allTexts)
        {
            text.font = font;
        }

        if (allTexts.Length > 0)
        {
            //用于刷新AssetDatabase的缓存和数据,使得最新的资源信息和项目状态能够在编辑器中正确显示和更新
            AssetDatabase.Refresh();
            Debug.Log("Changed all fonts in scene to: " + font.name);
        }
        else
        {
            Debug.Log("There are no fonts to change");
        }
    }


    /// <summary>
    /// 更换所有预制体中的字体
    /// </summary>
    /// <param name="font">选择的字体</param>
    private static void ChangeFontsInAllPrefabs(TMP_FontAsset font)
    {
        //查找所有预制体,并返回预制体资源的GUID(全局唯一标识符)数组
        string[] prefabPaths = AssetDatabase.FindAssets("t:Prefab");
        foreach (string prefabPath in prefabPaths)
        {
            //将资源的GUID(全局唯一标识符)转换为资源在项目中的路径
            string path = AssetDatabase.GUIDToAssetPath(prefabPath);
            //从指定路径加载资源对象
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);

            //预制体不为空 并且 预制体 不是 不可变的
            if (prefab != null && !PrefabUtility.IsPartOfImmutablePrefab(prefab))
            {
                //获取预制体中的所有 TextMeshPro 文本组件
                TMP_Text[] texts = prefab.GetComponentsInChildren<TMP_Text>(true);
                foreach (var text in texts)
                {
                    text.font = font;
                }
                //保存修改后的预制体
                PrefabUtility.SaveAsPrefabAsset(prefab, path);
            }
        }

        if (prefabPaths.Length > 0)
        {
            AssetDatabase.Refresh();
            Debug.Log("Changed all fonts in scene to: " + font.name);
        }
        else
        {
            Debug.Log("There are no fonts to change");
        }
    }

    /// <summary>
    /// 更换指定目录下的预制体中的字体
    /// </summary>
    /// <param name="font">选择的字体</param>
    /// <param name="directory">指定的目录,Assets/...</param>
    private static void ChangeFontsInPrefabsInDirectory(TMP_FontAsset font, string directory)
    {
        //AssetDatabase.FindAssets查找指定文件夹下的所有预制体路径
        //"t:Prefab" :查找条件,表示查找类型为预制体(Prefab)的资源
        //new[] { directory } : 指定查找的文件夹路径,如 "Assets/Resources" 
        //Select : LINQ 方法,用于对查找到的资源进行转换
        //AssetDatabase.GUIDToAssetPath将资源的 GUID 转换为实际的资源路径
        string[] prefabPaths = AssetDatabase.FindAssets("t:Prefab", new[] { directory }).Select(AssetDatabase.GUIDToAssetPath).ToArray();
        foreach (string path in prefabPaths)
        {
            //从指定路径加载资源对象
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
            //预制体不为空 并且 预制体 不是 不可变的
            if (prefab != null && !PrefabUtility.IsPartOfImmutablePrefab(prefab))
            {
                //更换预制体中所有文本组件的字体
                TMP_Text[] prefabTexts = prefab.GetComponentsInChildren<TMP_Text>(true);
                foreach (var text in prefabTexts)
                {
                    text.font = font;
                }

                //保存预制体更改
                PrefabUtility.SaveAsPrefabAsset(prefab, PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab), out bool success);
                if (success)
                {
                    AssetDatabase.Refresh();
                    Debug.Log($"Saved prefab: {prefab.name}");
                }
                else
                {
                    Debug.LogWarning($"Failed to save prefab: {prefab.name}");
                }
            }
        }

        if (prefabPaths.Length > 0)
        {
            Debug.Log("Changed all fonts in prefabs in " + directory + " to: " + font.name);
        }
        else
        {
            Debug.Log("There are no fonts to change");
        }
    }
}
相关推荐
mxwin7 小时前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
晚枫歌F9 小时前
三层时间轮的实现
网络·unity·游戏引擎
咸鱼永不翻身10 小时前
Lua脚本事件检查工具
unity·lua·工具
leo__52012 小时前
单载波中继系统资源分配算法MATLAB仿真程序
算法·matlab·unity
努力长头发的程序猿13 小时前
Unity使用ScriptableObject序列化资源
unity·游戏引擎
mxwin13 小时前
Unity Shader 手写基于 PBR 的 URP Lit Shader 核心光照计算
unity·游戏引擎·shader
小贺儿开发13 小时前
Unity3D 智能云端数字标牌系统
unity·阿里云·人机交互·视频·oss·广告·互动
魔士于安14 小时前
Unity windows 同步 异步 打开文件文件夹工具
游戏·unity·游戏引擎·贴图·模型
魔士于安14 小时前
unity lowpoly 风格 城市 建筑 道路 交通标志
游戏·unity·游戏引擎·贴图·模型
mxwin14 小时前
Unity GPU Shader 性能优化指南
unity·游戏引擎·shader