Unity制作更换字体的插件

news/2024/11/15 8:23:33/

目录

1.前置知识

1.1 EditorWindow

1)目的

2)使用方式

1.2 OnGUI()

1)目的

2)使用方式

1.3 AssetDatabase

1)目的

2)使用方式

1.4 PrefabUtility

1)目的

2)使用方式

2.代码

3.测试


       本篇文章来分享一下Unity如何制作更换字体的插件,可以快速更换场景中所有字体,更换所有预制体中的字体,更换指定路径下预制体中的字体。

1.前置知识

1.1 EditorWindow

1)目的

       自定义Unity功能插件,在Unity编辑器中显示,点击功能按钮后,弹出对应的窗口,可以在编辑器界面上直接进行操作。

2)使用方式

①自定义的类继承EditorWindow

②类中自定义一个静态方法ShowWindow,用于获取或创建EditorWindow窗口实例并显示它。这个方法用public static修饰,并且用MenuItem属性标记([MenuItem("Tools/Change Font")])。在该方法中调用EditorWindow.GetWindow方法。

EditorWindow.GetWindow是获取或创建自定义编辑器窗口的静态方法,用于创建自定义的编辑器

1.2 OnGUI()

1)目的

       自定义窗口布局,OnGUI属于Unity生命周期中的方法,可以看一下Unity生命周期。

2)使用方式

GUILayout:用于运行时和编辑器模式下的GUI元素布局。

EditorGUILayout:EditorGUILayout是GUILayout的扩展,增加了针对编辑器的特定功能。专门用于Unity编辑器窗口中创建和布局用户界面,在EditorWindow和自定义Editor脚本中使用。

1.3 AssetDatabase

1)目的

       对项目中的资源(Assets)进行查找,修改等操作。

       AssetDatabase是Unity编辑器中的一个静态类,提供了与项目中的资源(Assets)进行交互的功能。通 AssetDatabase,可以执行各种与资源管理相关的操作,包括创建、删除、移动、重命名资源,甚至检索资源的路径或信息等。主要用于编辑器脚本和自定义编辑器工具,对资源进行管理和操作。

2)使用方式

AssetDatabase.CreateAsset: 创建一个新的资产并保存到项目中。

AssetDatabase.ImportAsset: 强制导入或重新导入指定路径的资产。

AssetDatabase.DeleteAsset: 删除指定路径的资产。

AssetDatabase.MoveAsset: 移动资产到新的路径。

AssetDatabase.GetAssetPath: 获取指定对象的资源路径。

AssetDatabase.LoadAssetAtPath: 从指定路径加载资源对象。

AssetDatabase.Refresh: 刷新 AssetDatabase,以便 Unity 重新加载资源的变化。

AssetDatabase.SaveAssets: 保存对资源的修改。

AssetDatabase.FindAssets: 根据搜索条件(如标签、类型)查找资源。

AssetDatabase.GUIDToAssetPath: 将资源的GUID(全局唯一标识符)转换为其在项目中的路径

1.4 PrefabUtility

1)目的

       对资源中的预制体进行编辑、创建等操作。

       PrefabUtility是Unity编辑器中的一个静态类,用于操作和管理预制体(Prefab)。提供了对预制体的编辑、创建和应用操作的功能。PrefabUtility主要用于编辑器脚本,允许在编写自定义工具和自动化流程时对预制体进行各种操作。

2)使用方式

PrefabUtility.GetPrefabAssetType: 获取指定对象的预制体类型。

PrefabUtility.GetPrefabInstanceHandle: 获取预制体实例的句柄,用于编辑和修改实例。

PrefabUtility.ApplyPrefabInstance: 将对预制体实例所做的更改应用到预制体资产。

PrefabUtility.RevertPrefabInstance: 将预制体实例恢复为原始预制体资产的状态。

PrefabUtility.InstantiatePrefab: 实例化预制体资产并返回其实例。

PrefabUtility.SaveAsPrefabAsset: 将游戏对象保存为新的预制体资产。

PrefabUtility.IsPartOfImmutablePrefab: 判断一个游戏对象是否是一个不可变预制体(Immutable Prefab)的部分。不可变预制体是指无法修改其内容的预制体,通常用于在特定场景中保护预制体的完整性。

2.代码

using System.Linq;
using TMPro;
using UnityEditor;
using UnityEngine;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 Fonts In Scene")){if (selectedFont != null){ChangeAllFonts(selectedFont);}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 ChangeAllFonts(TMP_FontAsset font){//得到场景中的所有TMP_Text,并更换TMP_Text的字体TMP_Text[] allTexts = GameObject.FindObjectsOfType<TMP_Text>();foreach (TMP_Text 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");}}
}

3.测试

       在菜单选择“Change Font”,会弹出对应的窗口

       选择想要更换的字体,点击应用按钮即可进行更换。①“Apply All Fonts In Scene”:更换场景中所有字体;②“Apply All Fonts In All Prefabs”:更换所有预制体中的字体;③“Apply All Fonts In Prefabs In Directory”:更换指定路径下预制体中的字体,该目录相对于项目文件夹的路径,如Assets/...

 

       好了,本次的分享到这里就结束啦,希望对你有所帮助,优秀~


http://www.ppmy.cn/news/1522473.html

相关文章

GNU/Linux - Open函数使用的O_CLOEXEC flag

在 Linux 中&#xff0c;“O_CLOEXEC ”标志与 “open ”系统调用一起使用&#xff0c;用于指定在使用 “exec ”系列函数&#xff08;如 “execve”、“execl ”等&#xff09;执行新程序时&#xff0c;“open ”返回的文件描述符应自动关闭。 In Linux, the O_CLOEXEC flag i…

C++(多态性)

多态 多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数。 最简单的例子就是使用同样的运算符&#xff0c;可以实现整数与整数之间&#xff0c;浮点数与浮点数之间的加法运算。 多…

前端基础面试题·第一篇——HTML

1 .HTML标签头部< !DOCTYPE html> 的作用 DOCTYPE 使 document type的缩写&#xff0c;是html文档的类型声明&#xff0c;告诉浏览器文档的类型&#xff0c;便于解析文档。 这里会涉及到浏览器渲染页面的两种形式&#xff1a; CSS1 Compatible Mode(标准模式): 浏览器使…

Nginx反向代理功能及动静分离实现

一&#xff1a;Nginx支持正向代理和反向代理 1.正向代理 正向代理&#xff0c;指的是通过代理服务器 代理浏览器/客户端去重定向请求访问到目标服务器 的一种代理服务。 正向代理服务的特点是代理服务器 代理的对象是浏览器/客户端&#xff0c;也就是对于目标服务器 来说浏览…

共享内存和信号量

共享内存和信号量可以配合起来一起使用。 什么是共享内存&#xff1f;&#xff1a; 共享内存就是映射一段能被其他进程所访问的内存&#xff0c;这段共享内存由一个进程创建&#xff0c;但多个进程都可以访问。共享内存是最快的IPC方式&#xff0c;它是针对其他进程间通信方式…

漫谈设计模式 [8]:装饰器模式

引导性开场 菜鸟&#xff1a;老鸟&#xff0c;我最近在项目中遇到一个问题。有些功能&#xff0c;比如日志记录和权限校验&#xff0c;我需要在多个地方使用。代码很冗余&#xff0c;不知道有没有更好的解决办法&#xff1f; 老鸟&#xff1a;菜鸟&#xff0c;这个问题很常见…

FaskAPI Web学习

FaskAPI Web学习 个人笔记使用&#xff0c;感谢阅读&#xff01; # -*- ecoding: utf-8 -*- # Author: SuperLong # Email: miu_zxl163.com # Time: 2024/9/7 11:37 from enum import Enum from typing import Optionalfrom fastapi import FastAPI import uvicorn app FastA…

log4j 多classloader重复加载配置问题解决

最近OneCoder在开发隔离任务运行的沙箱&#xff0c;用于隔离用户不同任务间以及任务和 框架本身运行代码的隔离和解决潜在的jar包冲突问题。 运行发现&#xff0c;隔离的任务正常运行&#xff0c;但是却没有任何日志记录。从控制台可看到如下错误信息&#xff1a; 全文详见个人…