孙广东 2016.8.31
这个Unity在定制的时候就遇到问题, 最好(不是必须的, 可以自己实现啊)反射系统的,
下面有些代码是之前 的文章中介绍过的。 比如 scene 场景文件的 Inspector 面板显示。 文件夹的 Inspector面板显示等!!!
正常的逻辑做法; [CustomEditor(typeof(TextureImporter))] public class CustomTextureAssetInspector : Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); // 首先我希望显示默认的 系统的内容(但是不是我想要的!) string path = AssetDatabase.GetAssetPath(target); // 1 GUI.enabled = true; if (path.EndsWith(".png") || path.EndsWith(".jpg")) { if (GUILayout.Button("Setup2UI")) { } if (GUILayout.Button("Setup2SpineTexture")) { } } Debug.Log("=============显示 TextureAssetInspector ======"); } }
结果如下图所示, 这种肯定不是我想要的。
http://blog.csdn.net/u010019717
所以只能使用反射解决:
using UnityEngine; using System.Collections.Generic; using System.IO; using UnityEditor; using System.Reflection; using System; /// <summary> /// 描述:注: 音频、贴图、材质、预制体、模型、脚本、特殊不识别的资源等都不是 DefaultAsset /// author: 孙广东 /// </summary> [CustomEditor(typeof(UnityEditor.DefaultAsset))] public class CustomDefaultAssetInspector : Editor { #region ===字段=== private static string prePath = string.Empty; #endregion #region ===Unity事件=== 快捷键: Ctrl + Shift + M /Ctrl + Shift + Q 实现 // 1、如果是场景就显示 场景的所有引用。 // 2、如果是文件夹,就显示 文件夹下的所有文件和子目录 public override void OnInspectorGUI() { base.OnInspectorGUI(); string path = AssetDatabase.GetAssetPath(target); // 1 GUI.enabled = true; FileInfo fil = new FileInfo(path); if (fil.Attributes == FileAttributes.Directory)//判断类型是选择的是文件夹还是文件 { GUILayout.Label("文件夹下的所有内容:"); var filePaths = Directory.GetFiles(path, "*", SearchOption.AllDirectories); int i = 1; for (int j = 0; j < filePaths.Length; j++) { if (!filePaths[j].EndsWith(".meta")) { GUILayout.Label(i + "、" + filePaths[j]); i++; } } } } #endregion } [CustomEditor(typeof(UnityEditor.SceneAsset))] public class CustomSceneAssetInspector : Editor { public override void OnInspectorGUI() // todo 这个太卡了! { base.OnInspectorGUI(); string path = AssetDatabase.GetAssetPath(target); // 1 GUI.enabled = true; if (path.EndsWith(".unity")) { GUILayout.Label("场景的所有引用:"); var depends = AssetDatabase.GetDependencies(new[] { path }); for (int i = 0; i < depends.Length; i++) { GUILayout.Label(i + "、" + depends[i]); } } Debug.Log("=============显示 SceneAssetInspector ======"); } } // http://forum.unity3d.com/threads/custom-textureimporterinspector.260833/ [CustomEditor(typeof(TextureImporter))] public class CustomTextureAssetInspector : Editor { private SerializedObject serializedTarget; private Editor nativeEditor; public void OnEnable() { serializedTarget = new SerializedObject(target); SceneView.onSceneGUIDelegate = TargetUpdate; Type t = null; foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type type in assembly.GetTypes()) { if (type.Name.ToLower().Contains("textureimporterinspector")) { t = type; break; } } } nativeEditor = Editor.CreateEditor(serializedObject.targetObject, t); } void TargetUpdate(SceneView sceneview) { Event e = Event.current; } public override void OnInspectorGUI() { if (nativeEditor != null) { bool isCustom = false;// check ((TextureImporter)serializedObject.targetObject).assetPath for file formats you need if (isCustom) { // Do your stuff here // you can use ((TextureImporter)serializedObject.targetObject).userData to store your stuff between sessions } else { // 如果没有Header 相关的显示就解注下面的代码。 //MethodInfo dynMethod = nativeEditor.GetType().GetMethod("OnHeaderGUI", BindingFlags.NonPublic | BindingFlags.Instance); //dynMethod.Invoke(nativeEditor, new object[] { }); nativeEditor.OnInspectorGUI(); GUILayout.Space(50); if (GUILayout.Button("Setup2UI")) { string assetPath = AssetDatabase.GetAssetPath(target); TextureImporter texImport = AssetImporter.GetAtPath(assetPath) as TextureImporter; TextureImporterProcessor.SetSpriteTexture(texImport, assetPath); } if (GUILayout.Button("Setup2SpineTexture")) { string assetPath = AssetDatabase.GetAssetPath(target); TextureImporter texImport = AssetImporter.GetAtPath(assetPath) as TextureImporter; TextureImporterProcessor.SetSpineTexture(texImport, assetPath); } } } // Unfortuanaly we cant hide ImportedObject section because InspectorWindow check it by // if (editor is AssetImporterEditor) and all flags that this check sets are method local variables // so aside from direct patching UnityEditor.dll no luck for reflection here :( // in my case i just moved ImportedObject section out of view GUILayout.Space(2048); SceneView.RepaintAll(); } //protected override void OnHeaderGUI() //{ // // 注意: 这下面注释的两个方法都不行(这连个方法也不等价), 回到值Unity崩溃!(所以我就放在 OnInspectorGUI() 中调用了) // //base.DrawHeader(); // //MethodInfo dynMethod = nativeEditor.GetType().GetMethod("OnHeaderGUI", BindingFlags.NonPublic | BindingFlags.Instance); // //dynMethod.Invoke(nativeEditor, new object[] { }); //} //// todo 这是有问题的 案例!!!!! 所以必须要反射 //public override void OnInspectorGUI() //{ // DrawDefaultInspector(); // string path = AssetDatabase.GetAssetPath(target); // // 1 // GUI.enabled = true; // if (path.EndsWith(".png") || path.EndsWith(".jpg")) // { // if (GUILayout.Button("Setup2UI")) // { // } // if (GUILayout.Button("Setup2SpineTexture")) // { // } // } // Debug.Log("=============显示 TextureAssetInspector ======"); //} }
最终的结果就是这样了。
using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; public class TextureImporterProcessor/// : AssetPostprocessor { //// 系统调用 :导入的时候处理图片的设置 //void OnPreprocessTexture() //{ // TextureImporter texImport = assetImporter as TextureImporter; // // 没办法, 这个处理太容易触发, 就会出现强制设置, 无法特殊的更改了!!!!! // //if (assetPath.Contains("/Sprites/")) // //{ // // Debug.Log("导入时前处理 UI Sprite"); // // SetSpriteTexture(texImport, assetPath); // //} // //else if (assetPath.Contains("/Spines/")) // //{ // // Debug.Log("导入时前处理 Spine Texture"); // // SetSpineTexture(texImport, assetPath); // //} //} /// <summary> ///! 在这个函数中设置 UI 资源的标准 /// </summary> /// <param name="texImport"></param> /// <param name="assetPath"></param> public static void SetSpriteTexture(TextureImporter texImport, string assetPath) { texImport.textureType = TextureImporterType.Sprite; var tests = assetPath.Split('\\'); texImport.spritePackingTag = tests[tests.Length - 2]; // 所在文件夹的名字 作为图集的名字 texImport.mipmapEnabled = false; texImport.maxTextureSize = 2048; texImport.textureFormat = TextureImporterFormat.AutomaticCompressed; AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); // 这个导致资源导入,造成死循环啊 } /// <summary> ///! 在这个函数中设置 Spine图片 的标准 /// </summary> /// <param name="texImport"></param> public static void SetSpineTexture(TextureImporter texImport, string assetPath) { texImport.textureType = TextureImporterType.Advanced; texImport.spriteImportMode = SpriteImportMode.None; texImport.spritePackingTag = ""; texImport.alphaIsTransparency = false; texImport.mipmapEnabled = false; texImport.maxTextureSize = 2048; texImport.textureFormat = TextureImporterFormat.ETC2_RGBA8; AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } /////////////////////////////////// 通过菜单命令进行设置 /////////////////// static string withoutExtensions = "*.png*.jpg"; static string SpritePath = Application.dataPath + "\\Arts\\Sprites\\"; static string SpinePath = Application.dataPath + "\\Arts\\Spines\\"; [MenuItem("DajiaGame/Custom/SetupSpriteImage")] static void SetupSpriteImage() { string[] files = Directory.GetFiles(SpritePath, "*.*", SearchOption.AllDirectories) .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray(); //int startIndex = 0; // 不支持线程 bool keyCodeCancel = false; for (int startIndex = 0; startIndex < files.Length; startIndex++) { string assetPath = files[startIndex].Replace(Application.dataPath, "Assets"); bool isCancel = EditorUtility.DisplayCancelableProgressBar( "匹配资源中", assetPath, (float)startIndex / files.Length); TextureImporter texImport = AssetImporter.GetAtPath(assetPath) as TextureImporter; SetSpriteTexture(texImport, assetPath); if (isCancel || keyCodeCancel || startIndex >= files.Length) { EditorUtility.ClearProgressBar(); Debug.Log("设置结束"); EditorApplication.update = null; break; } } // 点击取消按钮 会很费劲,所以使用这个 EditorApplication.update = () => { if (Input.GetKeyDown(KeyCode.Escape)) { keyCodeCancel = true; Debug.LogError("取消了设置"); } }; } [MenuItem("DajiaGame/Custom/SetupSpineTexture")] static void SetupSpineTexture() { string[] files = Directory.GetFiles(SpinePath, "*.*", SearchOption.AllDirectories) .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray(); bool keyCodeCancel = false; for (int startIndex = 0; startIndex < files.Length; startIndex++) { string assetPath = files[startIndex]; bool isCancel = EditorUtility.DisplayCancelableProgressBar( "匹配资源中", assetPath, (float)startIndex / files.Length); TextureImporter texImport = AssetImporter.GetAtPath(assetPath) as TextureImporter; SetSpineTexture(texImport, assetPath); if (isCancel || keyCodeCancel || startIndex >= files.Length) { EditorUtility.ClearProgressBar(); Debug.Log("设置结束"); break; } } // 点击取消按钮 会很费劲,所以使用这个 EditorApplication.update = () => { if (Input.GetKeyDown(KeyCode.Escape)) { keyCodeCancel = true; Debug.LogError("取消了设置"); } }; } static Object[] GetSelectedTextures() { return Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets); } /////////////////////////////////// 通过菜单命令进行设置 /////////////////// }http://blog.csdn.net/u010019717