Unity制作更换字体的插件

news2025/1/11 18:43:38

目录

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.coloradmin.cn/o/2112504.html

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

相关文章

永远学习:为什么人工智能难以适应新挑战

理解深度学习的局限性并追求真正的持续适应 欢迎来到雲闪世界。 “智者适应环境&#xff0c;正如水适应水瓶。”——中国谚语 “适应或灭亡&#xff0c;现在和以往一样&#xff0c;是大自然的必然法则。”——赫伯特乔治威尔斯 近年来&#xff0c;人工智能取得了长足的进步。所…

Android的logcat日志详解

Android log系统 logcat介绍 logcat是android中的一个命令行工具&#xff0c;可以用于得到程序的log信息。下面介绍 adb logcat中的详细参数命令以及如何才能高效的打印日志&#xff0c;或把日志保存到我们指定的位置。 可以输入 adb logcat --help&#xff0c;查看一下一些简…

Xinstall助力App全渠道统计,参数传递下载提升用户体验!

在移动互联网时代&#xff0c;App已成为我们日常生活中不可或缺的一部分。然而&#xff0c;对于App开发者来说&#xff0c;如何有效地推广和运营自己的应用&#xff0c;却是一个不小的挑战。尤其是在面对众多渠道、复杂的数据统计和用户需求多样化的情况下&#xff0c;如何精准…

【ffmpeg】转换音频格式

在音频文件所在目录启动终端输入以下 ffmpeg -y -i original.aac target.mp3-y 如果输出文件已经存在&#xff0c;则覆盖它而不询问。 执行完毕后在当前文件夹目录下生成目标文件

项目9-网页聊天室9(测试报告)

1.项目背景 本项目采用 SSM框架结合 Websocket 技术构建。用户通过简单的注册和登录即可进入聊天室&#xff0c;与其他在线用户实时交 流。系统支持文字消息的快速发送和接收、消息实时推送&#xff0c;确保交流的及时性和流畅性。SSM 框架为项目提供了稳定的架构和高效的 数据…

学习笔记--MybatisPlus

官网&#xff1a;MyBatis-Plus &#x1f680; 为简化开发而生 快速入门 入门案例 引入MybatisPlus的起步依赖 定义Mapper 问题&#xff1a; MybatisPlus中Invalid bound statement (not found): com.itheima.mp.mapper.UserMapper.insert 一定要指定实体类&#xff01;&am…

ASTER 地表动能温度 (AST_08) 是利用 8 至 12 µm 光谱范围内的五个热红外波段

ASTER L2 Surface Temperature V00 简介 ASTER 地表动能温度 (AST_08) 是利用 8 至 12 m 光谱范围内的五个热红外波段&#xff08;白天或夜间获取&#xff09;生成的 (https://lpdaac.usgs.gov/documents/996/ASTER_Earthdata_Search_Order_Instructions.pdf)。 它只包含陆地…

Slideflow:数字病理学中的深度学习与全切片可视化工具库|文献精析·24-09-02

小罗碎碎念 群里今天有人提问Histolab相关的问题&#xff0c;作者在交流的过程中谈到了Slideflow&#xff0c;恰好我没有看过这篇文章&#xff0c;所以便有了这期推文。 作者角色作者姓名单位名称&#xff08;英文&#xff09;单位名称&#xff08;中文&#xff09;第一作者Jam…

性能工具之 JProfiler 简单登录案例分析实战

文章目录 一、前言二、准备工作三、使用JProfile定位问题四、登陆案例分析四、总结 一、前言 JProfiler是一款 Java的性能监控工具。可以查看当前应用的对象、对象引用、内存、CPU使用情况、线程、线程运行情况&#xff08;阻塞、等待等&#xff09;&#xff0c;同时可以查找应…

66、脑机接口产业联盟天津第一次全体大会参会分享

我注意到脑机联盟网上搜不到第一次和第二次大会的有关资料&#xff0c;这是非常遗憾的&#xff0c;所以我根据自己参会的记录&#xff0c;写成文章&#xff0c;与各位同学分享&#xff0c;此课件我也做成了公开课讲解&#xff0c;连接在我的Github。写这些&#xff0c;也算是为…

uAI - AI Assistant 人工智能辅助助手插件

uAI助手支持GPT 3.5 Turbo、GPT 3.5 Turbo16K、GPT 4-8k和GPT 4 Turbo-128k 什么是uAI助理? uAI Assistant是Unity游戏引擎的强大扩展,它使用GPT AI帮助游戏开发人员轻松创建专业代码和引人入胜的游戏内容。 你需要一个OpenAI密钥才能使用uAI助手!阅读我们的文档以获取更多说…

PDF 格式的文件编辑难度非常大,相比 .docx格式,它存在的意义是什么?

知乎上有个热门问题&#xff0c;PDF 格式的文件编辑难度非常大&#xff0c;相比 .docx格式&#xff0c;它存在的意义是什么&#xff1f; 回答这个问题得承认一个大前提&#xff0c;PDF是用来查看的&#xff0c;而不是编辑的。 否则就相当于提问&#xff0c;詹姆斯的足球踢得并…

Qt基础类03-直线类QLine

Qt基础类03-直线类QLine 摘要基本信息成员函数程序全貌QLine::QLine()QLine::QLine(const QPoint &p1, const QPoint &p2)QLine::QLine(int x1, int y1, int x2, int y2)QPoint QLine::p1() constQPoint QLine::p2() constint QLine::x1() constint QLine::x2() consti…

ComfyUI+Krea免费利用AI制作网站萌宠IP,五步搞定制作AI萌宠

大家好&#xff0c;这是我们网站的萌宠——Meo喵&#xff0c;是一只猫咪AI工具专家&#x1f43e;&#xff0c;嘻嘻&#x1f389;&#x1f431;。是AIGC年轻的艺术家星之&#xff0c;利用AI产品ComfyUI、Krea&#xff0c;搭配PS制作而成&#xff0c;下面先介绍一下它的形象&…

LLM大模型教程:langchain 教程

软件安装 pip install pymupdf pip install langchain pip install langchain-cli conda install -c pytorch -c nvidia faiss-gpu1.7.4 mkl2021 blas1.0mkl由于langchain不支持qwen模型&#xff0c;我们需要自定义模型 from typing import Anyfrom langchain_core.language_…

‌Python开发者必学:如何优雅地绕过round函数的四舍五入陷阱

引言 在最近交付测试的一个功能中&#xff0c;测试同学反馈一个数据统计四舍五入的问题&#xff0c;问题有点魔性&#xff1a;同样的条件&#xff0c;有的值可以四舍五入成功&#xff0c;有的值直接被舍弃。 例如2.5四舍五入整数直接变成了2&#xff1b;3.5却变成了4。因为使用…

IDEA 模板配置

IDEA 模板配置 一、tkMapper通用mapper配置 1 新建配置文件generatorConfig.xml&#xff0c;路径src/main/resources/generator/generatorConfig.xml <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE generatorConfigurationPUBLIC "-…

基于单片机的多功能电子钟设计

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP…

C学习(数据结构)-->排序

目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、快速排序 1、取基准值 1&#xff09;hoare找基准值​编辑 2&#xff09; 挖坑法找基准值​编辑 3&#xff09;快慢指针找基准值​编辑 2、递归快速排序 3、非递归快速排序 ​编辑 五、归并排序 ​编辑 六、计…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 9月7日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年9月7日 星期六 农历八月初五 白露 1、 司法部&#xff1a;遏制地方乱发文、出台“奇葩”政策文件等情况。 2、 证监会&#xff1a;拉长离职人员入股禁止期至10年&#xff0c;扩大对离职人员从严监管范围。 3、 全国医护比…