Firstborn/Assets/RPG Creation Kit/Scripts/Character System/Editor/RCKCustomiziationEditor.cs

227 lines
5.9 KiB
C#
Raw Normal View History

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