您的位置:首页 > 移动开发 > Unity3D

扩展 Unity的 TextureImporterEditor

2016-10-08 08:55 633 查看
孙广东  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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: