IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]扩展 Unity的 TextureImporterEditor

    u010019717发表于 2016-10-08 08:55:22
    love 0

    孙广东  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




沪ICP备19023445号-2号
友情链接