一键替换工程文件和场景中的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_NEWERText[] texts = GameObject.FindObjectsOfType<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}
#elseScene 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);}}
#endifreturn _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即可。

最后附上完整代码:

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>>();#endregionprivate 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_NEWERText[] texts = GameObject.FindObjectsOfType<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}
#elseScene 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);}}
#endifreturn _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("提示", "替换完毕!", "确定");}#endregionprivate List<GameObject> GetUseFontPrefabs(string font){if (Dic_Font_Prefabs.ContainsKey(font))return Dic_Font_Prefabs[font];elsereturn null;}private int GetGetUseFontPrefabCount(string font){List<GameObject> temp = GetUseFontPrefabs(font);return temp == null ? 0 : temp.Count;}#endregion
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/65853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nnUNet v2数据准备及格式转换 (二)

如果你曾经使用过nnUNet V1&#xff0c;那你一定明白数据集的命名是有严格要求的&#xff0c;必须按照特定的格式来进行命名才能正常使用。 这一节的学习需要有数据&#xff0c;如果你有自己的数据&#xff0c;可以拿自己的数据来实验&#xff0c;如果没有&#xff0c;可以用十…

ASP.NET Core 中的 静态文件

Static Files Static Files 包括 HTML&#xff0c;CSS&#xff0c;图片&#xff0c;JavaScript&#xff0c;以及其他静态资源文件。 即网站本身的内容。 Static Files 服务 Static Files 保存在项目的 Web Root 目录&#xff0c;即 wwwroot 文件夹中。 而wwwroot目录是Conte…

两个pdf文件合并为一个怎么操作?分享pdf合并操作步骤

不管是初入职场的小白&#xff0c;还是久经职场的高手&#xff0c;都必须深入了解pdf&#xff0c;特别是关于pdf的各种操作&#xff0c;如编辑、合并、压缩等操作&#xff0c;其中合并是这么多操作里面必需懂的技能之一&#xff0c;但是很多人还是不知道两个pdf文件合并为一个怎…

jenkins+ssh+Putty构建windows的IIS服务发布

使用JenkinssshPutty发布windows IIS服务 下面是使用Jenkins、SSH和PuTTY实现Windows IIS服务发布的步骤&#xff1a; 在构建服务器上安装Windows SSH服务、PuTTY和7-Zip软件。在部署服务器上也安装Windows SSH服务和7-Zip软件。在构建服务器上使用批处理命令执行编译&#x…

ChatGPT⼊门到精通(4):ChatGPT 为何⽜逼

⼀、通⽤型AI 在我们原始的幻想⾥&#xff0c;AI是基于对海量数据的学习&#xff0c;锻炼出⼀个⽆所不知⽆所不能的模 型&#xff0c;并借助计算机的优势&#xff08;计算速度、并发可能&#xff09;等碾压⼈类。 但我们⽬前的AI&#xff0c;不管是AlphaGo还是图像识别算法&am…

组件化开发之如何封装组件-react

组件化开发之如何封装组件-react 什么是组件为什么需要封装组件组件的分类函数组件&#xff08;Functional Components&#xff09;&#xff1a;展示型组件&#xff1a;容器型组件&#xff1a;知道组件分类的意义是&#xff1f; 如何拆分组件&#xff0c;需要遵循什么原则1.保证…

解决Debian系统通过cifs挂载smb后,中文目录乱码问题

解决Debian系统通过cifs挂载smb后&#xff0c;中文目录乱码问题 //$smb_server/share /mnt/nas_share cifs credentials/root/.smbcredentials,iocharsetutf8 0 0默认通过以上命令挂载smb&#xff0c;但是在查看文件目录时&#xff0c;中文乱码 解决问题方式&#xff1a; de…

MR混合现实汽车维修情景实训教学演示

MR混合现实技术应用于汽车维修课堂中&#xff0c;能够赋予学生更加真实&#xff0c;逼真地学习环境&#xff0c;让学生在情景体验中不断提高自己的专业能力。 MR混合现实汽车维修情景实训教学演示具体体现在&#xff1a; 1. 虚拟维修指导&#xff1a;利用MR技术&#xff0c;可…

企业架构LNMP学习笔记9

nginx配置文件定义php-fpm服务&#xff1a; 编写测试文件&#xff1a; vim /usr/local/nginx/html/index.php 内容&#xff1a; <?phpphpinfo(); 在nginx的配置文件中配置&#xff1a; 修改配置文件&#xff0c;告知nginx如果收到.php结尾的请求&#xff0c;交由给php-…

【数据结构篇】线性表1 --- 顺序表、链表 (万字详解!!)

前言&#xff1a;这篇博客我们重点讲 线性表中的顺序表、链表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列... 线性表在逻辑上是…

mac软件安装后打开软件显示损坏

#mac传输安装包后安装后打开软件显示损坏处理方式 以postman为例&#xff0c;输入前面的代码&#xff0c;打开访达&#xff0c;把有问题的软件拉到命令行窗口&#xff0c;确认即可 sudo xattr -r -d com.apple.quarantine /Applications/Postman.app sudo xattr -r -d com.ap…

如何中mac上安装多版本python并配置PATH

摘要 mac 默认安装的python是 python3&#xff0c;但是如果我们需要其他python版本时&#xff0c;该怎么办呢&#xff1f; 例如&#xff1a;需要python2 版本&#xff0c;如果使用homebrew安装会提示没有python2。同时使用python --version 会发现commond not found。 所以本…

MySQL中表的设计

在MySQL中表的设计&#xff0c;需要一定的经验才能理解&#xff0c;由于笔者目前在读中&#xff0c;理解不是很深刻&#xff0c;仅根据自己的想法外界的一些参考资料做出下述文字描述&#xff0c;一些错误&#xff0c;请大佬及时指正~~ 在本篇文章中&#xff0c;介绍一点简单粗…

RocketMQ(消息中间件)

目录 一、为什么会出现消息中间件&#xff1f; 二、消息中间件是干嘛的&#xff1f; 三、应用解耦 四、流量削峰 五、异步处理 1.串行方式&#xff1a; 2.并行方式&#xff1a; 3.引入消息队列&#xff1a; 六、RocketMQ的架构及概念 一、为什么会出现消息中间件&#…

k8s基于rbac权限管理serviceAccount授权管理

测试通过http访问apiServer curl没有证书不能通过https来访问apiServer需要使用kubectl代理 #使用kubectl代理 kubectl proxy --port8111& #curl访问 api/v1 是资源所属群组/版本 即创建资源时定义的apiVersion #后边跟的是要访问的资源 #查看所有命名空间 #查看核心资源用…

小程序快速备案助手代备案小程序开发

小程序快速备案助手代备案小程序开发 用户注册与登录&#xff1a;用户可以通过手机号或其他方式进行注册和登录&#xff0c;以便进行备案相关操作。备案信息填写&#xff1a;用户可以填写小程序的备案信息&#xff0c;包括小程序名称、小程序服务类目、域名等。备案材料上传&a…

Python钢筋混凝土结构计算.pdf-混凝土构件计算

计算原理&#xff1a; 代码实现&#xff1a; #钢筋混凝土参数 def c_hrb(): global fcuk,HRB,Ec,fc,ft,ftk,Es,fy,fyp,fyk global a1,epsilon_cu fcukEcfcftftk0.0 HRBEsfyfypfyk0.0 #矩形应力图系数a1&#xff0c;C50以下为1.0 a11.0 #正截面混凝土极限压应变epsilon_cu&#…

linux URL访问工具

URL访问工具 有时候想在命令行下通过http访问接口/网页&#xff0c;可以使用curl来进行操作 发起请求 curl www.baidu.com 会返回网页内容 参数选项 -i参数 使用-i参数&#xff0c;会返回响应header curl -i www.baidu.com -I参数 使用-I参数&#xff0c;只会返回响应header cu…

使用element-ui中的el-table回显已选中数据时toggleRowSelection报错

最近在写一个后台&#xff0c;需要在表格中多选&#xff0c;然后点击编辑按钮的时候&#xff0c;需要回显已经选中的表单项 <el-table v-loading"loading" :data"discountList" :row-key"(row) > row.id" refmultipleTable selection-cha…

LeetCode 面试题 02.05. 链表求和

文章目录 一、题目二、C# 题解 一、题目 给定两个用链表表示的整数&#xff0c;每个节点包含一个数位。 这些数位是反向存放的&#xff0c;也就是个位排在链表首部。 编写函数对这两个整数求和&#xff0c;并用链表形式返回结果。 点击此处跳转题目。 示例&#xff1a; 输入&a…