一键替换工程文件和场景中的UI对象字体

这篇具有很好参考价值的文章主要介绍了一键替换工程文件和场景中的UI对象字体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

具体流程:

  1. 找到工程中使用到的所有字体
  2. 找到工程和场景中包含Text的所有对象
  3. 展示要替换的字体名字让用户选择
  4. 通过用户选择的字体,展示响应的物体对象
  5. 一键替换

通过AssetDatabase.FindAssets找到工程中包含的所有字体:

 private List<string> FindAllFonts()
    {
        List<string> list = new List<string>();
        // 获取所有字体文件
        string[] fontGUIDs = AssetDatabase.FindAssets("t:Font");
        foreach (string fontGUID in fontGUIDs)
        {
            string fontPath = AssetDatabase.GUIDToAssetPath(fontGUID);
            Font font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);
            list.Add(font.name);
        }
        list.Add("Arial");//默认字体添加进去
        return list;
    }

 通过AssetDatabase.FindAssets找到工程中的所有预制体

  private List<GameObject> GetAllPrefabByAssetDatabase(params string[] path)
    {
        List<GameObject> _prefabList = new List<GameObject>();
        string[] _guids = AssetDatabase.FindAssets("t:Prefab", path);
        string _prefabPath = "";
        GameObject _prefab;
        foreach (var _guid in _guids)
        {
            _prefabPath = AssetDatabase.GUIDToAssetPath(_guid);
            _prefab = AssetDatabase.LoadAssetAtPath(_prefabPath, typeof(GameObject)) as GameObject;
            _prefabList.Add(_prefab);
        }
#if UNITY_2020_1_OR_NEWER
        Text[] texts = GameObject.FindObjectsOfType<Text>(true);
        foreach (var text in texts)
        {
            _prefabList.Add(text.gameObject);
        }
#else
        Scene activeScene = EditorSceneManager.GetActiveScene();
        GameObject[] allObjectsInScene = activeScene.GetRootGameObjects();
        foreach (var obj in allObjectsInScene)
        {
            Text[] texts = obj.GetComponentsInChildren<Text>(true);
            foreach (var text in texts)
            {
                _prefabList.Add(text.gameObject);
            }
        }
#endif
        return _prefabList;
    }

过滤没有含Text组件的对象

 private List<GameObject> FilterNoTextPrefabs()
    {
        List<GameObject> templist = new List<GameObject>();
        Dic_Font_Prefabs.Clear();
        foreach (var prefab in prefabs)
        {
            Text[] texts = prefab.GetComponentsInChildren<Text>(true);
            if (texts.Length != 0)
            {
                foreach (var text in texts)
                {
                    if (text.font != null)
                    {
                        if (!Dic_Font_Prefabs.ContainsKey(text.font.name))
                        {
                            Dic_Font_Prefabs.Add(text.font.name, new List<GameObject>());//根据Font类型,添加一个Text集合到字典中
                        }
                        if (!Dic_Font_Prefabs[text.font.name].Contains(prefab))
                        {
                            Dic_Font_Prefabs[text.font.name].Add(prefab);
                        }
                        if (!templist.Contains(prefab))
                        {
                            templist.Add(prefab);//包含该Text的预制体添加到集合中
                        }
                    }
                }
            }
        }
        return templist;
    }

最后,用户选择完要替换的字体,选择开始替换即可。

TextMeshPro跟Text是一个道理,只需要把代码中响应的Text和Font改为TextMeshProGUI和FontAssets即可。

最后附上完整代码:文章来源地址https://www.toymoban.com/news/detail-708516.html

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine.UI;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
/// <summary>
/// 查找替换工程场景中Text的Font
/// </summary>
public class ChangePrefabFont : EditorWindow
{
    [MenuItem("Tools/替换字体/Text")]//入口
    static void GetWindow()//静态函数
    {
        //创建窗口
        ChangePrefabFont window = EditorWindow.GetWindow<ChangePrefabFont>("Text字体替换窗口");//生成一个unity窗口弹窗
        window.Show();//展示OnGUI中的界面显示
    }

    #region 属性
    /// <summary>
    /// 工程中包含的字体的名字
    /// </summary>
    List<string> fontsOnAssets = new List<string>();
    /// <summary>
    /// 对应字体是否需要替换
    /// </summary>
    List<bool> textPaidFontRelpace = new List<bool>();
    /// <summary>
    /// 代替要替换的字体的字体
    /// </summary>
    List<Font> textReplaceFonts = new List<Font>();
    /// <summary>
    /// 预制体集合
    /// </summary>
    List<GameObject> prefabs = new List<GameObject>();
    /// <summary>
    /// 根据字体类型分类的预制体对象
    /// </summary>
    Dictionary<string, List<GameObject>> Dic_Font_Prefabs = new Dictionary<string, List<GameObject>>();
    #endregion
    private void OnEnable()
    {
        InitFont();
    }
    private void OnGUI()
    {
        InitPrefabs();
        #region 显示替换选项
        EditorGUILayout.LabelField("下面是工程中包含的字体,和工程中&场景中的对象使用的字体情况。请选择要替换的字体:");
        for (int i = 0; i < fontsOnAssets.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField($"更换[{fontsOnAssets[i]}]字体");
            textPaidFontRelpace[i] = EditorGUILayout.Toggle(textPaidFontRelpace[i], GUILayout.Width(position.width));//是否要替换当前字体的复选框
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField($"    预制体数量:{GetGetUseFontPrefabCount(fontsOnAssets[i])}");
            if (!textPaidFontRelpace[i])
            {
                if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i]))
                {
                    foreach (var item in Dic_Font_Prefabs[fontsOnAssets[i]])
                    {
                        if (prefabs.Contains(item))
                        {
                            prefabs.Remove(item);
                        }
                    }
                }
            }
            else
            {
                EditorGUILayout.LabelField($"代替【{fontsOnAssets[i]}】的字体:");
                textReplaceFonts[i] = (Font)EditorGUILayout.ObjectField(textReplaceFonts[i], typeof(Font), true);//代替的字体复选框

                if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i]))
                {
                    foreach (var item in Dic_Font_Prefabs[fontsOnAssets[i]])
                    {
                        if (!prefabs.Contains(item))
                        {
                            prefabs.Add(item);
                        }
                    }
                }
            }
            EditorGUILayout.EndHorizontal();
        }
        EditorGUILayout.Space();
        #endregion
        #region 开始替换操作
        if (GUILayout.Button("开始替换"))
        {
            if (textReplaceFonts == null || textReplaceFonts.Count == 0)
            {
                EditorUtility.DisplayDialog("提示", "没有字体!", "确定");
                return;
            }
            if (prefabs == null || prefabs.Count == 0)
            {
                EditorUtility.DisplayDialog("提示", "没有需要替换的对象!", "确定");
                return;
            }
            List<GameObject> ReplaceGo = new List<GameObject>();
            Dictionary<string, Font> Dic_Font_ReplaceFont = new Dictionary<string, Font>();
            for (int i = 0; i < textPaidFontRelpace.Count; i++)
            {
                if (textPaidFontRelpace[i] == true)
                {
                    if (textReplaceFonts[i] != null)
                    {
                        if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i]))
                        {
                            ReplaceGo.AddRange(Dic_Font_Prefabs[fontsOnAssets[i]]);
                            Dic_Font_ReplaceFont.Add(fontsOnAssets[i], textReplaceFonts[i]);
                        }
                        else
                        {
                            EditorUtility.DisplayDialog("提示", $"使用了【{fontsOnAssets[i]}】字体的预制体数量为0!", "确定");
                        }
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("提示", $"【{fontsOnAssets[i]}】的替代字体为空!", "确定");
                    }
                }
            }
            if (ReplaceGo.Count == 0)
            {
                EditorUtility.DisplayDialog("提示", "没有需要替换的对象!", "确定");
            }
            else
            {
                string hintInfo = "";
                foreach (var font in Dic_Font_ReplaceFont)
                {
                    hintInfo += $"{font.Key} >> {font.Value.name}\n";
                }
                if (EditorUtility.DisplayDialog("确认进行下面的替换?", hintInfo, "确定", "取消"))
                {
                    foreach (var font in Dic_Font_ReplaceFont)
                    {
                        ReplaceFont(Dic_Font_Prefabs[font.Key], font.Key, font.Value);
                    }
                    SaveChangedToAsset(prefabs);
                }
            }
        }
        #endregion
        #region 预制体列表
        InitReorderableList();
        if (reorderableList != null && reorderableList.count != 0)
        {
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            reorderableList.DoLayoutList();
            EditorGUILayout.EndScrollView();
        }
        else
        {
            EditorGUILayout.LabelField("提示:没有需要替换字体的预制体");
        }
        #endregion
    }
    #region 列表和滚动窗口
    ReorderableList reorderableList;//列表显示
    Vector2 scrollPos;//滚动窗口需要
    private void DrawHeader(Rect rect)
    {
        EditorGUI.LabelField(rect, "对象列表数量:" + prefabs.Count);
    }
    private void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
    {
        rect.height -= 4;
        rect.y += 2;
        prefabs[index] = (GameObject)EditorGUI.ObjectField(rect, "包含Text的对象", prefabs[index], typeof(GameObject), true);
    }
    private void AddItem(ReorderableList list)
    {
        prefabs.Add(null);
    }
    #endregion
    #region 逻辑方法
    /// <summary>
    /// 字体相关初始化
    /// </summary>
    private void InitFont()
    {
        textPaidFontRelpace.Clear();
        textReplaceFonts.Clear();
        fontsOnAssets = FindAllFonts();
        foreach (var item in fontsOnAssets)
        {
            textPaidFontRelpace.Add(false);
            textReplaceFonts.Add(null);
        }
    }
    /// <summary>
    /// 预制体相关初始化
    /// </summary>
    private void InitPrefabs()
    {
        prefabs = GetAllPrefabByAssetDatabase();
        prefabs = FilterNoTextPrefabs();
        prefabs.Clear();
        foreach (var item in Dic_Font_Prefabs)
        {
            prefabs.AddRange(item.Value);
        }

    }
    /// <summary>
    /// 初始化链表操作对象
    /// </summary>
    private void InitReorderableList()
    {
        prefabs = prefabs.Distinct().ToList();
        reorderableList = new ReorderableList(prefabs, typeof(GameObject), true, true, true, true);
        reorderableList.drawHeaderCallback = DrawHeader;
        reorderableList.drawElementCallback = DrawElement;
        reorderableList.onAddCallback = AddItem;
    }

    #endregion
    #region 功能方法
    #region 查找和过滤
    /// <summary>
    /// 找到工程和场景中的含有Text组件的对象
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private List<GameObject> GetAllPrefabByAssetDatabase(params string[] path)
    {
        List<GameObject> _prefabList = new List<GameObject>();
        string[] _guids = AssetDatabase.FindAssets("t:Prefab", path);
        string _prefabPath = "";
        GameObject _prefab;
        foreach (var _guid in _guids)
        {
            _prefabPath = AssetDatabase.GUIDToAssetPath(_guid);
            _prefab = AssetDatabase.LoadAssetAtPath(_prefabPath, typeof(GameObject)) as GameObject;
            _prefabList.Add(_prefab);
        }
#if UNITY_2020_1_OR_NEWER
        Text[] texts = GameObject.FindObjectsOfType<Text>(true);
        foreach (var text in texts)
        {
            _prefabList.Add(text.gameObject);
        }
#else
        Scene activeScene = EditorSceneManager.GetActiveScene();
        GameObject[] allObjectsInScene = activeScene.GetRootGameObjects();
        foreach (var obj in allObjectsInScene)
        {
            Text[] texts = obj.GetComponentsInChildren<Text>(true);
            foreach (var text in texts)
            {
                _prefabList.Add(text.gameObject);
            }
        }
#endif
        return _prefabList;
    }
    /// <summary>
    /// 过滤没有包含Text的预制体
    /// 过滤没有包含付费字体的预制体
    /// 根据Text类型分类
    /// </summary>
    /// <param name="gameObjects"></param>
    /// <returns></returns>
    private List<GameObject> FilterNoTextPrefabs()
    {
        List<GameObject> templist = new List<GameObject>();
        Dic_Font_Prefabs.Clear();
        foreach (var prefab in prefabs)
        {
            Text[] texts = prefab.GetComponentsInChildren<Text>(true);
            if (texts.Length != 0)
            {
                foreach (var text in texts)
                {
                    if (text.font != null)
                    {
                        if (!Dic_Font_Prefabs.ContainsKey(text.font.name))
                        {
                            Dic_Font_Prefabs.Add(text.font.name, new List<GameObject>());//根据Font类型,添加一个Text集合到字典中
                        }
                        if (!Dic_Font_Prefabs[text.font.name].Contains(prefab))
                        {
                            Dic_Font_Prefabs[text.font.name].Add(prefab);
                        }
                        if (!templist.Contains(prefab))
                        {
                            templist.Add(prefab);//包含该Text的预制体添加到集合中
                        }
                    }
                }
            }
        }
        return templist;
    }
    /// <summary>
    /// 找到工程中的所有字体文件
    /// </summary>
    /// <returns>返回字体名称列表</returns>
    private List<string> FindAllFonts()
    {
        List<string> list = new List<string>();
        // 获取所有字体文件
        string[] fontGUIDs = AssetDatabase.FindAssets("t:Font");
        foreach (string fontGUID in fontGUIDs)
        {
            string fontPath = AssetDatabase.GUIDToAssetPath(fontGUID);
            Font font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);
            list.Add(font.name);
        }
        list.Add("Arial");//默认字体添加进去
        return list;
    }
    #endregion
    #region 替换字体方法
    /// <summary>
    /// 替换Text的字体
    /// </summary>
    /// <param name="texts">要替换的Text集合</param>
    /// <param name="fontName">要替换的字体的名字</param>
    /// <param name="font">用来替换的字体</param>
    private void ReplaceFont(List<GameObject> gameObjects, string fontName, Font font)
    {
        foreach (var go in gameObjects)
        {
            Text[] texts = go.GetComponentsInChildren<Text>(true);
            foreach (var text in texts)
            {
                if (text.font != null)
                {
                    if (text.font.name == fontName)
                    {
                        text.font = font;
                    }
                }
                //else
                //{
                //    text.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
                //}
            }
        }
    }
    /// <summary>
    /// 保存更改
    /// </summary>
    /// <param name="gameObjects"></param>
    private void SaveChangedToAsset(List<GameObject> gameObjects)
    {
        foreach (var gameObject in gameObjects)
        {
            EditorUtility.SetDirty(gameObject);
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        EditorUtility.DisplayDialog("提示", "替换完毕!", "确定");
    }
    #endregion
    private List<GameObject> GetUseFontPrefabs(string font)
    {
        if (Dic_Font_Prefabs.ContainsKey(font))
            return Dic_Font_Prefabs[font];
        else
            return null;
    }
    private int GetGetUseFontPrefabCount(string font)
    {
        List<GameObject> temp = GetUseFontPrefabs(font);
        return temp == null ? 0 : temp.Count;
    }
    #endregion
}

到了这里,关于一键替换工程文件和场景中的UI对象字体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Pycharm一键将.ui文件生成.py文件配置教程、一键打开QTDesigner教程

    2df3621a-7ffd-4f18-9735-b86464b83a5b 前言 我痛恨所有将白嫖归为理所应当的猪🐖。 教程 打开pycharm之后,依次点击File-Settings-Tools-External Tools,进入如下界面: 1、配置快捷打开Qt Designer 点击+号,开始我们的配置,首先配置快捷打开Qt Designer软件的配置项,配置了之后,我们直接点击

    2024年01月16日
    浏览(48)
  • 文件名替换,关键字替换改名:不同路径中的多个文件如何批量重命名

    在日常生活和工作中,我们经常需要处理大量的文件,包括重命名、分类、整理等操作。其中,批量重命名不同路径中的多个文件是一项非常常见的任务。本文将介绍云炫文件管理器常见的批量重命名方法:文件名替换改名,帮助您轻松应对不同路径中的多个文件的重

    2024年02月08日
    浏览(79)
  • 【嵌入式】字体极限瘦身术:Fontmin在嵌入式UI中的魔法应用(附3500常用汉字)

    🧑 作者简介 :阿里巴巴嵌入式技术专家,深耕嵌入式+人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍 :分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导、简历面试辅导、技术架构设计优化、开发外包等

    2024年03月11日
    浏览(65)
  • 【python技巧】替换文件中的某几行

    最近在写一个后端项目,主要的操作就是根据用户的前端数据,在后端打开项目中的代码文件,修改对应位置的参数,因为在目前的后端项目中经常使用这个操作,所以简单总结一下。 读取文件 使用python中的open()函数进行文件读取,将数据存储在缓冲区。 查找文件替换位置

    2024年02月09日
    浏览(39)
  • 【STM32开发小技巧】CUBEMX改变工程模板(FreeMarker一键生成定制文件)

    ps:可直接跳到效果展示 众所周知CUBEMX可以生成代码,图形界面可以方便用户进行STM32的配置,有天我就在想能否用户改变生成后的代码,于是就有了下面的文章。 直接进入Project Manager页面。 我们看一下官方的说明 生成了一些外设信息,这些都是通过FreeMarker模板引擎代码生成

    2023年04月08日
    浏览(79)
  • Android Framework 全局替换系统字体

    基于Android 11 Android Framework 全局替换系统字体 将需要替换的字体资源放置frameworks/base/data/fonts/目录下。 将系统默认的Roboto字体替换为HarmonyOs字体。 frameworks/base/data/fonts/fonts.xml frameworks/base/data/fonts/Android.mk frameworks/base/data/fonts/fonts.mk 编译刷机验证。 frameworks/base/graphics/java/and

    2024年02月12日
    浏览(40)
  • 掌握文件重命名快捷键,使用替换功能轻松删除文件名中的符号!

    您是否经常面对繁琐的文件重命名工作?是时候掌握一些文件管理的小技巧,让您的工作更加高效便捷了!现在,我们向您介绍一种简单的方法,通过文件重命名快捷键和替换功能,轻松删除文件名中的符号! 首先,我们要打开文件批量改名高手,并在板块栏里选择“文件批

    2024年02月14日
    浏览(47)
  • 实用VBA:17.大量word文件中的文本内容进行批量替换

    在工作中可能会遇到需要对大量word文件中的文字内容进行批量替换的情况。相比excel的批量处理,个人感觉word文档中由于包含大量样式信息,批处理时总感觉有顾虑。一者担心影响了文档的格式,误修改了文档的样式,那后果……整过文档的小伙伴都懂的;二者担心批处理不

    2024年01月25日
    浏览(42)
  • Unity如何保存场景,如何导出工程文件/如何查看保存位置?【各版本通用】

    下图,保存场景不在Scenes文件夹下: 下图,保存在Scenes文件夹下: 下图,保存完成 下图,是具体步骤演示:

    2024年02月05日
    浏览(43)
  • Unity技能工厂——字体替换工具功能的实现!

    在平常我们做任何项目的时候,工具类对于我们来说是必不可少的组成部分,因为工具类可以解决实际问题或者是优化我们已经实现的功能。 当你在做项目的时候,搭建完场景后,前场景中你所创建的UI组件中的Text的字体并不符合你的要求,效果不好或者说是与你的游戏主题

    2024年02月02日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包