扩展 Unity的 TextureImporterEditor

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

扩展 Unity的 TextureImporterEditor_第1张图片



所以只能使用反射解决:

using UnityEngine;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using System.Reflection;
using System;

/// 
/// 描述:注: 音频、贴图、材质、预制体、模型、脚本、特殊不识别的资源等都不是 DefaultAsset
/// author: 孙广东
/// 
[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 ======");
    //}
}



最终的结果就是这样了。

扩展 Unity的 TextureImporterEditor_第2张图片


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

    /// 
    ///! 在这个函数中设置  UI 资源的标准
    /// 
    /// 
    /// 
    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);  // 这个导致资源导入,造成死循环啊
    }

    /// 
    ///! 在这个函数中设置  Spine图片 的标准
    /// 
    /// 
    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


你可能感兴趣的:(unity3d,Editor私人定制)