一、什么是 AssertPostprocessor 官方解释: AssetPostprocessor 允许您挂接到导入管线并在导入资源前后运行脚本。
详情见官方 API 介绍: AssetPostprocessor
如果项目中需要导入的资源较多,资源的属性就需要在 Inspector 面板中一个一个的进行配置,这很麻烦。而 AssetPostprocessor 可以在我们导入资源时,Unity 自动帮我们将资源的属性按照我们在脚本里写的设置配置好。
一些常用的方法如下:
二、简单应用实列1、在 Assets 文件夹下新建一个 Editor 文件夹,
关于 Editor 文件夹:
该文件夹可以放在项目的任何文件夹下,可以有多个”Editor”文件夹。
编辑器扩展相关的脚本都要放在该文件夹内,该文件夹中的脚本只会对 Unity 编辑器起作用。
项目打包的时候,不会被打包到项目中。如果编辑器相关脚本不放在该文件夹中,打包项目可能会出错。
如果非要有些编辑器相关脚本不放在该文件夹中,需要在该类的前后加上 UNITY_EDITOR 的宏定义
关于 Editor Default Resources 文件夹
必须放在 Project 视图的根目录下,可以把编辑器用到的一些资源放在这里。该文件夹和 Editor 文件夹一样都不会被打到最终发布包里,仅仅用于开发时使用。可以直接通过 EditorGUIUtility.Load 去读取该文件夹下的资源。
2、在 Editor 下面新建一个 C#脚本,该脚本必须继承自 AssetPostprocessor
【具体代码】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using UnityEngine;using UnityEditor;public class MyEditor : AssetPostprocessor { public void OnPreprocessTexture () { Debug.Log ("纹理资源预处理: " +this .assetPath); TextureImporter impor = this .assetImporter as TextureImporter; impor.textureType = TextureImporterType.Sprite; impor.alphaSource = TextureImporterAlphaSource.FromGrayScale; impor.isReadable = true ; } public static void OnPostprocessAllAssets (string [] importedAssets,string [] deletedAssets,string [] movedAssets,string [] movedFromAssetPaths ) { Debug.Log ("======================资源发生变化=========================" ); foreach (string str in importedAssets) { Debug.Log("重新导入资源: " + str); } foreach (string str in deletedAssets) { Debug.Log("删除资源: " + str); } for (int i = 0 ; i < movedAssets.Length; i++) { Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]); } } }
3、将资源拖入项目中,即可实现资源属性的自动配置
【效果】
将图片拖入后,Inspector 面板设置如下
三、打包并使用编辑器 1、创建一个自定义的包 具体细则见官方文档: 创建自定义包
【标准包布局】 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <root> ├── package.json ├── README.md ├── CHANGELOG.md ├── LICENSE.md ├── Editor │ ├── Unity.[YourPackageName].Editor.asmdef │ └── EditorExample.cs ├── Runtime │ ├── Unity.[YourPackageName].asmdef │ └── RuntimeExample.cs ├── Tests │ ├── Editor │ │ ├── Unity.[YourPackageName].Editor.Tests.asmdef │ │ └── EditorExampleTest.cs │ └── Runtime │ ├── Unity.[YourPackageName].Tests.asmdef │ └── RuntimeExampleTest.cs └── Documentation~ └── [YourPackageName].md
【Package 命名规范】
包名起始必须为 com.,例如 com.unity.timeline
若在 UI 显示则需低于 50 个字符,否则可低于 214 个字符
仅包含小写字母、数字、连字符-、下划线_和点.
为表明命名空间,可在命名空间后缀加点。如 com.unity.2d.animation 和 com.unity.2d.ik
以下是简化版的步骤,并不规范 。
首先在 项目名/Packages 目录下创建一个文件夹作为自定义的包,在该文件夹下创建一个 Editor 文件夹、一个 Runtime 文件夹、一个 package.json 文件,在 Editor 文件夹下创建 MyTextureImportProcess.cs 、MyPackage.EditorTests.asmdef。
1 2 3 4 5 6 <root> ├── package.json ├── Editor │ ├── MyPackage.EditorTests.asmdef │ └── MyTextureImportProcess.cs └── Runtime
MyPackage.EditorTests.asmdef 的标准格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 { "name" : "MyPackage.Editor.Tests" , "references" : [ "MyPackage.Editor" , "MyPackage" ], "optionalUnityReferences" : [ "TestAssemblies" ], "includePlatforms" : [ "Editor" ], "excludePlatforms" : [] }
此处仅为测试用,所以可以稍作修改
1 2 3 4 5 6 7 8 { "name" : "EKKO测试.Editor.Tests" , "rootNamespace" : "" , "references" : [], "autoReferenced" : true , }
1 2 3 4 5 6 7 8 { "name" : "com.ekko.ekko-package" , "displayName" :"EKKO测试package" , "version" : "1.0.1" , "author" : "EKKO" , "description" : "这是一个测试" }
2、编辑器开发 (1)创建编辑器 先写一个工具函数
1 2 3 4 5 6 7 8 9 public class MyTools { public static string GetParentPath (string path ) { var str = path.Split("/" ); path = path.Replace(str[str.Length - 1 ], "" ); return path; } }
首先在代码中加上
1 [CreateAssetMenu(menuName = "EKKO/图片资源导入配置" , fileName = "图片资源导入配置" ) ]
此时在 Unity 中右键即可看到创建面板
注意: 点击创建后不要重命名
然后创建一个类继承自 ScriptableObject
1 2 3 4 public class MyTextureImportProcessSetting : ScriptableObject { }
注:
MonoBehaviour 是以组件形式挂在 GameObject 上的,而 ScriptableObject 则以 Assets 资源的形式存在的
类中写上要进行的设置,此处依据需要自定义
1 2 3 4 5 6 [Header("图片导入设置" ) ] [Space(10) ] public TextureImporterType textureType = TextureImporterType.NormalMap;public bool sRGB = true ;public bool readAble = true ;
unity 编辑器开发需要引用 UnityEditor 命名空间,并且脚本需要继承 Editor 类,用于在 Unity 软件界面编辑自己的控件。
CustormEditor 一般与类 Editor 配合使用,以实现在 Inspector 面板中的自定义显示,使用时有几个注意点:
1、CustomEditor + typeof + 类名
2、自定义类是 Editor 的派生类
3、绘制自定义 UI 要重写 OnInspectorGUI 函数。此函数是虚函数
1 2 3 4 5 6 [CustomEditor(typeof(MyTextureImportProcessSetting)) ] internal class TextureImportSetting : Editor { private MyTextureImportProcessSetting myTarget; }
继承 UnityEditor 脚本的几个基本事件函数,详情查看官方文档 。
OnEnable() 在挂载目标脚本的物体被选中时调用。
OnInspectorGUI() 在 Inspector 面板绘制自定义 UI 的语句必须在这个函数中执行。
OnSceneGUI() 在场景视图中绘制自定义 UI 的语句必须在这个函数执行。
OnDestory() 在脚本被销毁时调用。
在 OnEnable()函数中添加
1 myTarget = target as MyTextureImportProcessSetting;
在 OnInspectorGUI()函数中添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 base .OnInspectorGUI();if (GUILayout.Button("应用" )){ var path = AssetDatabase.GetAssetPath(myTarget); var files = Directory.GetFiles(MyTools.GetParentPath(path)); foreach (var file in files) { if (dir.IndexOf(".jpg" ) > 0 || dir.IndexOf(".png" ) > 0 || dir.IndexOf(".tga" ) > 0 ) { AssetDatabase.ImportAsset(file); } } }
(2) 使用设置 对上述简单应用实例 脚本进行修改,将 OnPreprocessTexture()函数修改为:
1 2 3 4 5 6 7 8 9 10 11 TextureImporter impor = this .assetImporter as TextureImporter; var parentPath = MyTools.GetParentPath(this .assetPath);var settings = AssetDatabase.LoadAssetAtPath<MyTextureImportProcessSetting>( parentPath + "图片资源导入配置.asset" );if (settings){ Debug.Log("纹理资源: " + this .assetPath + " 使用了自定义的配置" ); impor.textureType = settings .textureType; impor.sRGBTexture = settings .sRGB; impor.isReadable = settings .readAble; }
3、效果展示 首先将图片拖入 Unity 工程下的文件夹中
当前图片属性设置如下
在该文件夹下创建一个编辑器
对编辑器进行设置并点击应用
可以看到图片属性已经被重新设置
此时控制台的打印如下
四、扩展 以上功能仅限于与 “图片资源导入配置.asset” 处于同一文件夹中的纹理图片资源生效 如果要扩展,使得对该目录中的子文件夹里面的图片也生效,可以使用
1 2 3 4 5 6 7 var dirs = Directory.GetDirectories(path);foreach (var dir in dirs){ AssetDatabase.ImportAsset(dir, ImportAssetOptions.ImportRecursive); }
其中 ImportAssetOptions.ImportRecursive 功能为在导入一个文件时,同时导入其内容,详情见官方 API 介绍
五、项目源码 项目源码: GitHub 地址