当前位置: 首页 > news >正文

2024-06-10 Unity 编辑器开发之编辑器拓展10 —— 其他常见工具类

文章目录

  • 1 AssetDatabase
    • 1.1 准备工作
    • 1.2 常用 API
  • 2 PrefabUtility
    • 1 准备工作
    • 2 常用 API
  • 3 EditorApplication
    • 3.1 准备工作
    • 3.2 常用 API
  • 4 CompilationPipeline
    • 4.1 CompilationPipeline.assemblyCompilationFinished
    • 4.2 CompilationPipeline.compilationFinished
    • 4.3 示例
  • 5 AssetPostprocessor
    • 5.1 常用 API
    • 5.2 示例
  • 6 AssetImporter

1 AssetDatabase

​ AssetDatabase 是 Unity 引擎中的一个编辑器类,用于在编辑器环境中管理和操作项目中的资源(Assets)。

​ 它提供一系列静态方法,使得开发者能够在编辑器脚本中进行资源的创建、拷贝、移动、删除等操作。

​ 在编辑器相关处都可以使用 AssetDatabase,但它属于编辑器功能,无法被打包出去,只能在 Unity 编辑器中使用。

1.1 准备工作

​ AssetDatabase 可以在任何编辑器功能开发时使用,但为了讲解方便,这里通过一个自定义窗口来进行讲解。

using UnityEditor;
using UnityEngine;public class Lesson42Window : EditorWindow
{[MenuItem("Unity 编辑器拓展/Lesson42/AssetDatabase 知识讲解")]public static void Open() {Lesson42Window win = GetWindow<Lesson42Window>();win.Show();}private void OnGUI() { }
}

1.2 常用 API

  1. 创建资源
public static extern void CreateAsset(UnityEngine.Object asset, string path);// 示例:
private void OnGUI() {if (GUILayout.Button("创建资源")) {var mat = new Material(Shader.Find("Legacy Shaders/Specular"));AssetDatabase.CreateAsset(mat, "Assets/Resources/MyMaterial.mat");}
}
  • 路径从 Assets/… 开始,且文件夹必须存在。
  • 不能在 StreamingAssets 中创建资源。
  • 不能创建预设体(需使用 PrefabUtility 创建)。
  • 只能创建资源相关,例如材质球等。
  • 路径需要写后缀。
  1. 创建文件夹
public static extern string CreateFolder(string parentFolder, string newFolderName);// 示例:
private void OnGUI() {if (GUILayout.Button("创建文件夹")) {AssetDatabase.CreateFolder("Assets/Resources", "MyFolder");}
}
  • 路径从 Assets/… 开始。
  • 路径需要写后缀。
  1. 拷贝资源
public static extern bool CopyAsset(string path, string newPath);// 示例:
private void OnGUI() {if (GUILayout.Button("拷贝资源")) {AssetDatabase.CopyAsset("Assets/Resources/MyMaterial.mat", "Assets/Resources/newMaterial.mat");}
}
  • 路径从 Assets/… 开始。
  • 路径需要写后缀。
  1. 移动资源
public static extern bool DeleteAsset(string path);
public static bool DeleteAssets(string[] paths, List<string> outFailedPaths);// 示例:
private void OnGUI() {if (GUILayout.Button("删除资源")) {AssetDatabase.DeleteAsset("Assets/Resources/newMaterial2.mat");}
}
  • 路径从 Assets/… 开始。
  • 路径需要写后缀。
  • 目标资源不存在不会报错。
  1. 获取资源路径
public static extern string GetAssetPath(UnityEngine.Object assetObject);// 示例:
private void OnGUI() {if (GUILayout.Button("获取资源路径")) {Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));}
}
  • 可以配合 Selection 选中资源一起使用。
  1. 加载资源
public static T LoadAssetAtPath<T>(string assetPath) where T : UnityEngine.Object;
public static extern UnityEngine.Object[] LoadAllAssetsAtPath(string assetPath);// 示例:
private void OnGUI() {if (GUILayout.Button("加载资源")) {var mat = AssetDatabase.LoadAssetAtPath<Material>("Assets/Resources/newMaterial.mat");Debug.Log(mat.name);}
}
  • 路径从 Assets/… 开始。

  • 路径需要写后缀。

  • LoadAllAssetsAtPath 一般可以用来加载图集资源,返回值为 Object 数据。

    如果是图集,第一个为图集本身,之后的便是图集中的所有 Sprite。

  1. 刷新
public static void Refresh();
  • AssetDatabase 的 API 内部会自动调用刷新。使用其他操作时需要手动刷新。
  1. 获取资源 AB 包名称
public static extern string GetImplicitAssetBundleName(string assetPath);
  • 路径从 Assets/… 开始。

更多内容:https://docs.unity3d.com/ScriptReference/AssetDatabase.html

2 PrefabUtility

​ PrefabUtility 是 Unity 编辑器中的一个公共类,提供一些用于处理 Prefab(预制体或称预设体)的方法。
​ 主要功能包括:实例化预制体、创建预制体、修改预制体等等。

1 准备工作

using UnityEditor;
using UnityEngine;public class Lesson44Window : EditorWindow
{[MenuItem("Unity 编辑器拓展/Lesson44/PrefabUtility 知识讲解")]public static void Open() {Lesson44Window win = GetWindow<Lesson44Window>();win.Show();}private void OnGUI() { }
}

2 常用 API

  1. 创建预设体
public static GameObject SaveAsPrefabAsset(GameObject instanceRoot, string assetPath);// 示例:
private void OnGUI() {if (GUILayout.Button("动态创建预设体")) {GameObject obj = new GameObject();obj.AddComponent<Rigidbody>();obj.AddComponent<BoxCollider>();PrefabUtility.SaveAsPrefabAsset(obj, "Assets/Resources/TestObj.prefab");DestroyImmediate(obj); // 立即删除 obj}
}
  1. 加载预制体
public static GameObject LoadPrefabContents(string assetPath);
public static void UnloadPrefabContents(GameObject contentsRoot);// 示例:
private void OnGUI() {if (GUILayout.Button("加载预制体对象")) {GameObject testObj = PrefabUtility.LoadPrefabContents("Assets/Resources/TestObj.prefab");testObj.AddComponent<MeshRenderer>();PrefabUtility.SaveAsPrefabAsset(testObj, "Assets/Resources/TestObj.prefab"); // 需要新建预制体保存PrefabUtility.UnloadPrefabContents(testObj);}
}
  • 加载到内存中,不能用来实例化,一般加载出来进行修改。
  • 该方法的加载其实已经实例化了预设体,但该实例化对象并在 Scene 窗口中,而是在一个看不见的独立的场景中。
  • 可以进行脚本移除,子对象创建等操作。
  • 两个方法需要配对使用,加载了就要释放。
  1. 修改预设体
public static GameObject SavePrefabAsset(GameObject asset);
public static GameObject SavePrefabAsset(GameObject asset, out bool savedSuccessfully);// 示例:
private void OnGUI() {if (GUILayout.Button("修改已有预设体")) {GameObject testObj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/TestObj.prefab");testObj.AddComponent<BoxCollider>();PrefabUtility.SavePrefabAsset(testObj);}
}
  • 该方法不能存储实例化后的内容,只能存储对应的预设体对象。
  1. 实例化预制体
public static UnityEngine.Object InstantiatePrefab(UnityEngine.Object assetComponentOrGameObject);// 示例:
private void OnGUI() {if (GUILayout.Button("实例化预设体")) {GameObject testObj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/TestObj.prefab");PrefabUtility.InstantiatePrefab(testObj);}
}

更多内容:https://docs.unity3d.com/2022.3/Documentation/ScriptReference/PrefabUtility.html

3 EditorApplication

​ EditorApplication 是 Unity 编辑器中的一个公共类,主要提供和编辑器本身相关的一些功能。
​ 例如,编辑器事件监听(播放、暂停等)、生命周期判断(是否运行中、暂停中、编译中)、编辑器进入播放模式、退出播放模式等等。

3.1 准备工作

using UnityEditor;
using UnityEngine;public class Lesson45Window : EditorWindow
{[MenuItem("Unity 编辑器拓展/Lesson45/EditorApplication 知识讲解")]public static void Open() {Lesson45Window win = GetWindow<Lesson45Window>();win.Show();}private void OnEnable() {// 添加监听事件EditorApplication.update += ...;}private void OnDestroy() {// 移除监听事件EditorApplication.update -= ...;}
}

3.2 常用 API

  1. 监听编辑器事件

    • EditorApplication.update:每帧更新事件,可以用于在编辑器中执行一些逻辑。
    • EditorApplication.hierarchyChanged:层级视图变化事件,当场景中的对象发生变化时触发。
    • EditorApplication.projectChanged:项目变化事件,当项目中的资源发生变化时触发。
    • EditorApplication.playModeStateChanged:编辑器播放状态变化时触发。
    • EditorApplication.pauseStateChanged:编辑器暂停状态变化时触发。
  2. 管理编辑器生命周期相关

    • EditorApplication.isPlaying:判断当前是否处于游戏运行状态。
    • EditorApplication.isPaused:判断当前游戏是否处于暂停状态。
    • EditorApplication.isCompiling:判断 Unity 编辑器是否正在编译代码。
    • EditorApplication.isUpdating:判断 Unity 编辑器是否正在刷新 AssetDatabase。
  3. 获取 Unity 应用程序路径相关

    • EditorApplication.applicationContentsPath:Unity 安装目录 Data 路径。
    • EditorApplication.applicationPath:Unity 安装目录可执行程序路径。
  4. 常用方法

    • EditorApplication.Exit(0):退出 Unity 编辑器。
    • EditorApplication.ExitPlaymode():退出播放模式,切换到编辑模式。
    • EditorApplication.EnterPlaymode():进入播放模式。

更多内容:

  • EditorApplication:https://docs.unity3d.com/2022.3/Documentation/ScriptReference/EditorApplication.html

  • EditorSceneManager:https://docs.unity3d.com/2022.3/Documentation/ScriptReference/SceneManagement.EditorSceneManager.html

4 CompilationPipeline

​ CompilationPipeline 是 Unity 编辑器中的一个公共类,用于处理代码编译相关的操作和事件,通常使用它得知代码是否编译结束。

​ 比如动态生成脚本时,需要在编译结束后才能使用新的脚本。

4.1 CompilationPipeline.assemblyCompilationFinished

  • 命名空间:UnityEditor.Compilation;
  • 主要作用:当一个程序集编译结束会主动调用该回调函数。
  • 参数:
    • string arg1:编译完成的程序集名。
    • CompilerMessage[] arg2:编译完成后产生的编译消息数组,包括编译警告和错误信息。

4.2 CompilationPipeline.compilationFinished

  • 命名空间:UnityEditor.Compilation;
  • 主要作用:当所有程序集编译结束会主动调用该回调函数。
  • 参数:
    • object obj:ActiveBuildStatus 活动生成状态对象。

4.3 示例

using UnityEditor;
using UnityEditor.Compilation;
using UnityEngine;public class Lesson46Window : EditorWindow
{[MenuItem("Unity 编辑器拓展/Lesson46/CompilationPipeline 知识讲解")]public static void Open() {Lesson46Window win = GetWindow<Lesson46Window>();win.Show();}private void OnEnable() {CompilationPipeline.assemblyCompilationFinished += CompilationPipeline_assemblyCompilationFinished;CompilationPipeline.compilationFinished         += CompilationPipeline_compilationFinished;}private void CompilationPipeline_compilationFinished(object obj) {Debug.Log("所有程序集编译结束");}private void CompilationPipeline_assemblyCompilationFinished(string arg1, CompilerMessage[] arg2) {Debug.Log("程序集名:" + arg1);}private void OnDestroy() {CompilationPipeline.assemblyCompilationFinished -= CompilationPipeline_assemblyCompilationFinished;}
}

更多内容:https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline.html

5 AssetPostprocessor

​ AssetPostprocessor(资源后处理器)主要用于处理资源导入时的通用逻辑,可以通过继承该类并实现其中的一些回调方法来自定义处理资源。

​ 一般会进行以下处理:

  1. 进行某种类型资源的通用设置。
  2. 对某种类型资源进行统一批量的处理。

5.1 常用 API

  1. 常用属性:

    • AssetImporter assetImporter:对应类型的资源导入器对象。
    • string assetPath:导入资源的路径。
  2. 常用回调方法:

    • void OnPreprocessTexture():导入纹理资源之前调用,允许修改纹理的导入设置。
    • void OnPostprocessTexture(Texture2D texture):导入纹理资源之后调用,允许对导入后为其进行后处理,例如修改纹理格式、尺寸、压缩等等。
    • void OnPreprocessModel():导入模型资源之前调用,允许修改纹理的导入设置。
    • void OnPostprocessModel(GameObject obj):导入模型资源之后调用,允许对导入后为其进行后处理,例如修改网格、材质、动画等。
    • void OnPreprocessAudio():导入音频资源之前调用,允许修改纹理的导入设置。
    • void OnPostprocessAudio(AudioClip clip):导入音频资源之后调用,允许对导入后为其进行后处理,例如修改音频格式、质量等。
    • 等等

    注意:如果只想对某种资源中的某些内容进行处理,可以自己加命名规则。

更多内容:https://docs.unity3d.com/ScriptReference/AssetPostprocessor.html

5.2 示例

using UnityEditor;
using UnityEngine;public class Lesson47 : AssetPostprocessor
{void OnPreprocessTexture() { }void OnPostprocessTexture(Texture2D texture) {Debug.Log("纹理后处理回调" + texture.name);// 设置压缩格式EditorUtility.CompressTexture(texture, TextureFormat.ETC_RGB4, TextureCompressionQuality.Fast);}void OnPreprocessModel() { }void OnPostprocessModel(GameObject obj) { }void OnPreprocessAudio() { }void OnPostprocessAudio(AudioClip clip) { }
}

6 AssetImporter

​ AssetImporter(资源导入器)是特定资源类型的资源导入程序的基类,用于配置和管理资源的导入设置。

​ 一般不会直接使用该类,而是通过使用继承它的子类来设置导入资源的相关信息。

​ 当我们导入一个资源时,在 Inspector 窗口中进行的相关设置都是通过继承该类的子类实现的。

分类:

  1. TextureImporter:纹理导入器。
  2. ModelImporter:模型导入器。
  3. AudioImporter:音频导入器。
  4. VideoClipImporter:视频导入器。
  5. ScriptedImporter:自定义的资源导入器,对特定格式的资源进行自定义配置处理。

​ 使用示例:

using UnityEditor;
using UnityEngine;public class Lesson47 : AssetPostprocessor
{void OnPreprocessTexture() {Debug.Log("纹理设置回调" + assetPath);// 进行导入设置TextureImporter importer = (TextureImporter) assetImporter; // TextureImporterimporter.textureType   = TextureImporterType.Sprite;importer.mipmapEnabled = false;}void OnPostprocessTexture(Texture2D texture) { }void OnPreprocessModel() {TextureImporter importer = (ModelImporter) assetImporter; // ModelImporter}void OnPostprocessModel(GameObject obj) { }void OnPreprocessAudio() {TextureImporter importer = (AudioImporter) assetImporter; // AudioImporter}void OnPostprocessAudio(AudioClip clip) { }
}

更多内容:

  • TextureImporter:https://docs.unity3d.com/ScriptReference/TextureImporter.html
  • ModelImporter:https://docs.unity3d.com/ScriptReference/ModelImporter.html
  • AudioImporter:https://docs.unity3d.com/ScriptReference/AudioImporter.html
  • VideoClipImporter:https://docs.unity3d.com/ScriptReference/VideoClipImporter.html
  • ScriptedImporter:https://docs.unity3d.com/ScriptReference/AssetImporters.ScriptedImporter.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • VueRouter路由与Vuex状态管理
  • Python中使用SQLite和SQLAlchemy
  • 拐点已至:企业如何借助AI重塑增长?
  • flask项目结构与蓝图【心得】
  • 【设计模式】结构型-桥接模式
  • 计算机网络ppt和课后题总结(下)
  • vue2自定义指令
  • AI 边缘计算平台 - 回归开源 BeagleY-AI 简介
  • 机器学习-13-基于决策树算法构建北京市空气质量预测模型(实战)
  • 从零开始精通Onvif之获取设备信息
  • 绿联Nas docker 中 redis 老访问失败的排查
  • PhpStorm 项目部署/与git提交操作
  • java定时任务 设置开始时间、结束时间;每周一、四、六执行;并且隔n周执行。最后计算所有执行时间
  • GPT-4o:OpenAI的最新篇章与深度探索
  • 每日两题6
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 2017-08-04 前端日报
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Android优雅地处理按钮重复点击
  • classpath对获取配置文件的影响
  • co模块的前端实现
  • ESLint简单操作
  • JavaScript创建对象的四种方式
  • js对象的深浅拷贝
  • mysql_config not found
  • React Native移动开发实战-3-实现页面间的数据传递
  • vuex 学习笔记 01
  • 仿天猫超市收藏抛物线动画工具库
  • 如何编写一个可升级的智能合约
  • 数据仓库的几种建模方法
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ​iOS实时查看App运行日志
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (007)XHTML文档之标题——h1~h6
  • (1)Nginx简介和安装教程
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (笔试题)合法字符串
  • (九十四)函数和二维数组
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)VirtualBox安装增强功能
  • .Net 6.0--通用帮助类--FileHelper
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .Net Remoting(分离服务程序实现) - Part.3
  • .net 设置默认首页
  • .net 无限分类
  • .NET 中让 Task 支持带超时的异步等待
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET是什么
  • .Net中ListT 泛型转成DataTable、DataSet
  • /bin、/sbin、/usr/bin、/usr/sbin
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题