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

文章目录

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

1 AssetDatabase

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

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

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

1.1 准备工作

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

csharp 复制代码
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. 创建资源
csharp 复制代码
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. 创建文件夹
csharp 复制代码
public static extern string CreateFolder(string parentFolder, string newFolderName);

// 示例:
private void OnGUI() {
    if (GUILayout.Button("创建文件夹")) {
        AssetDatabase.CreateFolder("Assets/Resources", "MyFolder");
    }
}
  • 路径从 Assets/... 开始。
  • 路径需要写后缀。
  1. 拷贝资源
csharp 复制代码
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. 移动资源
csharp 复制代码
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. 获取资源路径
csharp 复制代码
public static extern string GetAssetPath(UnityEngine.Object assetObject);

// 示例:
private void OnGUI() {
    if (GUILayout.Button("获取资源路径")) {
        Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));
    }
}
  • 可以配合 Selection 选中资源一起使用。
  1. 加载资源
csharp 复制代码
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. 刷新
csharp 复制代码
public static void Refresh();
  • AssetDatabase 的 API 内部会自动调用刷新。使用其他操作时需要手动刷新。
  1. 获取资源 AB 包名称
csharp 复制代码
public static extern string GetImplicitAssetBundleName(string assetPath);
  • 路径从 Assets/... 开始。

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

2 PrefabUtility

​ PrefabUtility 是 Unity 编辑器中的一个公共类,提供一些用于处理 Prefab(预制体或称预设体)的方法。

​ 主要功能包括:实例化预制体、创建预制体、修改预制体等等。

1 准备工作

csharp 复制代码
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. 创建预设体
csharp 复制代码
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. 加载预制体
csharp 复制代码
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. 修改预设体
csharp 复制代码
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. 实例化预制体
csharp 复制代码
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 准备工作

csharp 复制代码
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():进入播放模式。

更多内容:

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 示例

csharp 复制代码
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 示例

csharp 复制代码
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:自定义的资源导入器,对特定格式的资源进行自定义配置处理。

​ 使用示例:

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class Lesson47 : AssetPostprocessor
{
    void OnPreprocessTexture() {
        Debug.Log("纹理设置回调" + assetPath);

        // 进行导入设置
        TextureImporter importer = (TextureImporter) assetImporter; // TextureImporter
        importer.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) { }
}

更多内容:

相关推荐
浔川python社2 小时前
关于浔川代码编辑器 v5.0 网页版上线时间的通知
编辑器
在路上看风景5 小时前
31. Unity 异步加载的底层细节
unity
天人合一peng6 小时前
Unity中做表头时像work中整个调整宽窄
unity
浔川python社6 小时前
浔川代码编辑器 v5.0 上线时间公布
编辑器
山峰哥16 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
Doro再努力16 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
Doro再努力16 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
小李也疯狂18 小时前
Unity 中的立方体贴图(Cubemaps)
unity·游戏引擎·贴图·cubemap
牛掰是怎么形成的18 小时前
Unity材质贴图引用陷阱:包体暴涨真相
unity·材质·贴图
呆呆敲代码的小Y18 小时前
【Unity工具篇】| 超实用工具LuBan,快速上手使用
游戏·unity·游戏引擎·unity插件·luban·免费游戏·游戏配置表