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

2024-06-14 1352阅读

文章目录

  • 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)。

              2024-06-10 Unity 编辑器开发之编辑器拓展10 —— 其他常见工具类
              (图片来源网络,侵删)

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

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

              1.1 准备工作

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

              using UnityEditor;
              using UnityEngine;
              public class Lesson42Window : EditorWindow
              {
                  [MenuItem("Unity 编辑器拓展/Lesson42/AssetDatabase 知识讲解")]
                  public static void Open() {
                      Lesson42Window win = GetWindow();
                      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 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(string assetPath) where T : UnityEngine.Object;
                        public static extern UnityEngine.Object[] LoadAllAssetsAtPath(string assetPath);
                        // 示例:
                        private void OnGUI() {
                            if (GUILayout.Button("加载资源")) {
                                var mat = AssetDatabase.LoadAssetAtPath("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();
                                      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();
                                      obj.AddComponent();
                                      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();
                                      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("Assets/Resources/TestObj.prefab");
                                        testObj.AddComponent();
                                        PrefabUtility.SavePrefabAsset(testObj);
                                    }
                                }
                                
                                • 该方法不能存储实例化后的内容,只能存储对应的预设体对象。
                                  1. 实例化预制体
                                  public static UnityEngine.Object InstantiatePrefab(UnityEngine.Object assetComponentOrGameObject);
                                  // 示例:
                                  private void OnGUI() {
                                      if (GUILayout.Button("实例化预设体")) {
                                          GameObject testObj = AssetDatabase.LoadAssetAtPath("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();
                                          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:编辑器暂停状态变化时触发。
                                    • 管理编辑器生命周期相关

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

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

                                          • 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();
                                                    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:导入资源的路径。
                                              • 常用回调方法:

                                                • 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; // 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) { }
                                            }
                                            

                                            更多内容:

                                            • 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
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]