227 lines
5.9 KiB
C#
227 lines
5.9 KiB
C#
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEditor;
|
|||
|
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// A base class for creating editors that decorate Unity's built-in editor types.
|
|||
|
/// </summary>
|
|||
|
public abstract class DecoratorEditor : Editor
|
|||
|
{
|
|||
|
// empty array for invoking methods using reflection
|
|||
|
private static readonly object[] EMPTY_ARRAY = new object[0];
|
|||
|
|
|||
|
#region Editor Fields
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Type object for the internally used (decorated) editor.
|
|||
|
/// </summary>
|
|||
|
private System.Type decoratedEditorType;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Type object for the object that is edited by this editor.
|
|||
|
/// </summary>
|
|||
|
private System.Type editedObjectType;
|
|||
|
|
|||
|
private Editor editorInstance;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
private static Dictionary<string, MethodInfo> decoratedMethods = new Dictionary<string, MethodInfo>();
|
|||
|
|
|||
|
private static Assembly editorAssembly = Assembly.GetAssembly(typeof(Editor));
|
|||
|
|
|||
|
protected Editor EditorInstance
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (editorInstance == null && targets != null && targets.Length > 0)
|
|||
|
{
|
|||
|
editorInstance = Editor.CreateEditor(targets, decoratedEditorType);
|
|||
|
}
|
|||
|
|
|||
|
if (editorInstance == null)
|
|||
|
{
|
|||
|
Debug.LogError("Could not create editor !");
|
|||
|
}
|
|||
|
|
|||
|
return editorInstance;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public DecoratorEditor(string editorTypeName)
|
|||
|
{
|
|||
|
this.decoratedEditorType = editorAssembly.GetTypes().Where(t => t.Name == editorTypeName).FirstOrDefault();
|
|||
|
|
|||
|
Init();
|
|||
|
|
|||
|
// Check CustomEditor types.
|
|||
|
var originalEditedType = GetCustomEditorType(decoratedEditorType);
|
|||
|
|
|||
|
if (originalEditedType != editedObjectType)
|
|||
|
{
|
|||
|
throw new System.ArgumentException(
|
|||
|
string.Format("Type {0} does not match the editor {1} type {2}",
|
|||
|
editedObjectType, editorTypeName, originalEditedType));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private System.Type GetCustomEditorType(System.Type type)
|
|||
|
{
|
|||
|
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
|
|||
|
|
|||
|
var attributes = type.GetCustomAttributes(typeof(CustomEditor), true) as CustomEditor[];
|
|||
|
var field = attributes.Select(editor => editor.GetType().GetField("m_InspectedType", flags)).First();
|
|||
|
|
|||
|
return field.GetValue(attributes[0]) as System.Type;
|
|||
|
}
|
|||
|
|
|||
|
private void Init()
|
|||
|
{
|
|||
|
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
|
|||
|
|
|||
|
var attributes = this.GetType().GetCustomAttributes(typeof(CustomEditor), true) as CustomEditor[];
|
|||
|
var field = attributes.Select(editor => editor.GetType().GetField("m_InspectedType", flags)).First();
|
|||
|
|
|||
|
editedObjectType = field.GetValue(attributes[0]) as System.Type;
|
|||
|
}
|
|||
|
|
|||
|
void OnDisable()
|
|||
|
{
|
|||
|
if (editorInstance != null)
|
|||
|
{
|
|||
|
DestroyImmediate(editorInstance);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Delegates a method call with the given name to the decorated editor instance.
|
|||
|
/// </summary>
|
|||
|
protected void CallInspectorMethod(string methodName)
|
|||
|
{
|
|||
|
MethodInfo method = null;
|
|||
|
|
|||
|
// Add MethodInfo to cache
|
|||
|
if (!decoratedMethods.ContainsKey(methodName))
|
|||
|
{
|
|||
|
var flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
|||
|
|
|||
|
method = decoratedEditorType.GetMethod(methodName, flags);
|
|||
|
|
|||
|
if (method != null)
|
|||
|
{
|
|||
|
decoratedMethods[methodName] = method;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogError(string.Format("Could not find method {0}", method));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
method = decoratedMethods[methodName];
|
|||
|
}
|
|||
|
|
|||
|
if (method != null)
|
|||
|
{
|
|||
|
method.Invoke(EditorInstance, EMPTY_ARRAY);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void OnSceneGUI()
|
|||
|
{
|
|||
|
CallInspectorMethod("OnSceneGUI");
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnHeaderGUI()
|
|||
|
{
|
|||
|
CallInspectorMethod("OnHeaderGUI");
|
|||
|
}
|
|||
|
|
|||
|
public override void OnInspectorGUI()
|
|||
|
{
|
|||
|
EditorInstance.OnInspectorGUI();
|
|||
|
}
|
|||
|
|
|||
|
public override void DrawPreview(Rect previewArea)
|
|||
|
{
|
|||
|
EditorInstance.DrawPreview(previewArea);
|
|||
|
}
|
|||
|
|
|||
|
public override string GetInfoString()
|
|||
|
{
|
|||
|
return EditorInstance.GetInfoString();
|
|||
|
}
|
|||
|
|
|||
|
public override GUIContent GetPreviewTitle()
|
|||
|
{
|
|||
|
return EditorInstance.GetPreviewTitle();
|
|||
|
}
|
|||
|
|
|||
|
public override bool HasPreviewGUI()
|
|||
|
{
|
|||
|
return EditorInstance.HasPreviewGUI();
|
|||
|
}
|
|||
|
|
|||
|
public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
|
|||
|
{
|
|||
|
EditorInstance.OnInteractivePreviewGUI(r, background);
|
|||
|
}
|
|||
|
|
|||
|
public override void OnPreviewGUI(Rect r, GUIStyle background)
|
|||
|
{
|
|||
|
EditorInstance.OnPreviewGUI(r, background);
|
|||
|
}
|
|||
|
|
|||
|
public override void OnPreviewSettings()
|
|||
|
{
|
|||
|
EditorInstance.OnPreviewSettings();
|
|||
|
}
|
|||
|
|
|||
|
public override void ReloadPreviewInstances()
|
|||
|
{
|
|||
|
EditorInstance.ReloadPreviewInstances();
|
|||
|
}
|
|||
|
|
|||
|
public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
|
|||
|
{
|
|||
|
return EditorInstance.RenderStaticPreview(assetPath, subAssets, width, height);
|
|||
|
}
|
|||
|
|
|||
|
public override bool RequiresConstantRepaint()
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public override bool UseDefaultMargins()
|
|||
|
{
|
|||
|
return EditorInstance.UseDefaultMargins();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class RCKCustomiziationEditor : Editor
|
|||
|
{
|
|||
|
public override bool RequiresConstantRepaint()
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public override void ReloadPreviewInstances()
|
|||
|
{
|
|||
|
base.ReloadPreviewInstances();
|
|||
|
}
|
|||
|
|
|||
|
public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
|
|||
|
{
|
|||
|
base.OnInteractivePreviewGUI(r, background);
|
|||
|
}
|
|||
|
|
|||
|
public override void OnPreviewSettings()
|
|||
|
{
|
|||
|
base.OnPreviewSettings();
|
|||
|
}
|
|||
|
|
|||
|
}
|