代码参自:http://anchan828.github.io/editor-manual/web/customeditor.html
之前已经讨论过场景中物体在Inspector面板的显示的更改,今天讨论一下Project面板中资源在Inspector面板的显示。例如,点击Project里一个C#脚本,在Inspector面板就会出现脚本内容的预览,但是项目中的lua文件点击了却不会这样显示。
所以,我们点击资源时,更具资源的后缀名来选择显示在Inspector面板的内容,例如,lua文件点击了可以直接把文本内容显示在Inspector面板。
效果:(点击的是lua文件,为了保密,内容替换为一组任意文字)
代码:
因为资源文件可能有很多种后缀名,不同的可能需求也不一样,所以我们写个属性类,不同需求的使用不同的属性:
-
public class CustomAssetAttribute : Attribute {
-
public string[] extensions; //不同属性对应不同需求,同一需求可能有几种类型文件
-
public CustomAssetAttribute(params string[] extention)
-
{
-
this.extensions = extention;
-
}
-
}
然后以lua文件这种文本资源为例,面板绘制:
-
/// <summary>
-
/// lua文件绘制方式
-
/// </summary>
-
[CustomAsset(".lua")] //绘制方式绑定以.lua为后缀的资源文件
-
public class LuaInspector : Editor
-
{
-
private string content;
-
private bool show = false;
-
private string showKey = "LuaInspectorShown";
-
void OnEnable()
-
{
-
string path = Application.dataPath + "/" + AssetDatabase.GetAssetPath(Selection.activeObject).Substring(7);
-
try
-
{
-
TextReader tr = new StreamReader(path);
-
content = tr.ReadToEnd(); //读取文件中所有文本
-
tr.Close();
-
}
-
catch (Exception e)
-
{
-
Debug.Log(e);
-
}
-
}
-
public override void OnInspectorGUI()
-
{
-
show = EditorPrefs.GetBool("showKey");
-
show = GUILayout.Toggle(show, "Show Lua Content");
-
EditorPrefs.SetBool("showKey", show);
-
if (show) //这里为了性能,加了开关
-
{
-
GUILayout.Label(content);
-
}
-
}
-
}
目前可见这两个文件关联性不大,第二个脚本设置了绘制方式,但是还没法使以.lua后缀的文件就以这种方式绘制了,于是有了:
-
[CustomEditor(typeof(DefaultAsset))] //自定义--资源的Inspector绘制方式
-
public class DefaultAssetInspector : Editor
-
{
-
private Editor editor; //资源文件预览绘制方式
-
private static Type[] customAssetTypes;
-
[InitializeOnLoadMethod] //Unity软件启动事件
-
static void Init()
-
{
-
customAssetTypes = GetCustomAssetTypes();
-
}
-
/// <summary>
-
/// 获取所有带自定义属性CustomAssetAttribute的类
-
/// </summary>
-
private static Type[] GetCustomAssetTypes()
-
{
-
var assemblyPaths = Directory.GetFiles("Library/ScriptAssemblies", "*.dll");
-
var types = new List<Type>();
-
var customAssetTypes = new List<Type>();
-
foreach (var assembly in assemblyPaths
-
.Select(assemblyPath => Assembly.LoadFile(assemblyPath)))
-
{
-
types.AddRange(assembly.GetTypes());
-
}
-
//到这一步,所有的类都在types这个列表里
-
foreach (var type in types)
-
{
-
//在每个类中尝试寻找使用自定义属性CustomAssetAttribute
-
var customAttributes =
-
type.GetCustomAttributes(typeof(CustomAssetAttribute), false) //获取自定义属性CustomAssetAttribute
-
as CustomAssetAttribute[];
-
if (0 < customAttributes.Length)
-
customAssetTypes.Add(type); //找到了就把这个类存到customAssetTypes列表中
-
}
-
//so返回的是所有程序集中找到的带CustomAssetAttribute属性的类的数组(如前面的LuaInspector类)
-
return customAssetTypes.ToArray();
-
}
-
/// <summary>
-
/// 根据扩展名去含指定属性的类数组中获取对应类(对比属性的extensions值)
-
/// </summary>
-
private Type GetCustomAssetEditorType(string extension)
-
{
-
foreach (var type in customAssetTypes)
-
{
-
var customAttributes =
-
type.GetCustomAttributes(typeof(CustomAssetAttribute), false)
-
as CustomAssetAttribute[];
-
foreach (var customAttribute in customAttributes)
-
{
-
if (customAttribute.extensions.Contains(extension))
-
return type;
-
}
-
}
-
return typeof(DefaultAsset);
-
}
-
private void OnEnable()
-
{
-
var assetPath = AssetDatabase.GetAssetPath(target);
-
var extension = Path.GetExtension(assetPath); //获取扩展名
-
//根据扩展名去得对应的继承自Editor的绘制方式
-
var customAssetEditorType = GetCustomAssetEditorType(extension);
-
//使目标以指定绘制方式绘制
-
editor = CreateEditor(target, customAssetEditorType);
-
}
-
//先去程序集中遍历寻找带有CustomAssetAttribute这个自定义的属性的类,找到这些个类后,就得到了后缀名和对应绘制方式
-
//(因为这个属性关联了后缀名和绘制方式)
-
//所以我们去用现在点击的资源的后缀名去获取对应的绘制方式,用这种方式绘制Inspector面板
-
public override void OnInspectorGUI()
-
{
-
if (editor != null)
-
{
-
GUI.enabled = true;
-
editor.OnInspectorGUI();
-
}
-
}
-
public override bool HasPreviewGUI() //是否有Inspector面板下面的预览小界面
-
{
-
return editor != null ? editor.HasPreviewGUI() : base.HasPreviewGUI();
-
}
-
public override void OnPreviewGUI(Rect r, GUIStyle background) //小界面内容
-
{
-
if (editor != null)
-
editor.OnPreviewGUI(r, background);
-
}
-
public override void OnPreviewSettings() //小界面横条设置内容
-
{
-
if (editor != null)
-
editor.OnPreviewSettings();
-
}
-
public override string GetInfoString()
-
{
-
return editor != null ? editor.GetInfoString() : base.GetInfoString();
-
}
-
}
代码很详细,要说的都在代码里,然后OK了。
但是,lua脚本过长,Unity里会报错没法绘制了,所以脚本大小要控制,进一步方法待思考开发。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
简单说一下Inspector面板下面的预览小面板,一般模型什么的会用到这个。
如,上述改为:
-
//是否有Inspector面板下面的预览小界面
-
public override bool HasPreviewGUI()
-
{
-
return true;
-
//return editor != null ? editor.HasPreviewGUI() : base.HasPreviewGUI();
-
}
-
public override void OnPreviewGUI(Rect r, GUIStyle background)
-
{
-
//if (editor != null)
-
// editor.OnPreviewGUI(r, background);
-
GUI.Label(r, "Preview \n This is preview content!");
-
}
-
public override void OnPreviewSettings() //小界面横条设置内容
-
{
-
//if (editor != null)
-
// editor.OnPreviewSettings();
-
GUIStyle preLabel = new GUIStyle("preLabel");
-
GUIStyle preButton = new GUIStyle("preButton");
-
GUILayout.Label("EanLabel", preLabel);
-
GUILayout.Button("EamBtn", preButton);
-
}
-
public override string GetInfoString()
-
{
-
return "Here Info";// editor != null ? editor.GetInfoString() : base.GetInfoString();
-
}
-
public override GUIContent GetPreviewTitle()
-
{
-
return new GUIContent("Here Title");
-
}
结合图片说明一下: