不影响Inspector布局拓展类
DecoratorEditor.cs
using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; /// <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 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(); /*System.Type[] types = editorAssembly.GetTypes(); for (int i=0; i<types.Length; i++) { string name=types[i].Name; if(name.IndexOf("Collider")>-1)Debug.Log(name); }*/ Init (); // Check CustomEditor types. /*var originalEditedType = GetCustomEditorType(decoratedEditorType); Debug.Log(originalEditedType); 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 (); } //5.x才有以下方法 /*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 EditorInstance.RequiresConstantRepaint (); } public override bool UseDefaultMargins () { return EditorInstance.UseDefaultMargins (); } }