unity3d 扩展unity原有的Inspector
2016-03-29 09:58
537 查看
为什么会影响到原有布局呢?原因是这样的上面的代码是继承Editor的,那么base.OnInspectorGUI()实际上去掉用了Editor类里的OnInspectorGUI()方法,可是RectTransfm的OnInspectorGUI()方法是在RectTransformEditor这个类写的。
但是问题就来了,RectTransformEditor这个类不是一个对外公开的类。所以不能继承它,那也就无法调用它的OnInspectorGUI()方法了,所以就有了上述问题。
这里有一个巧妙的反射方法,完美的解决这个问题。https://gist.github.com/liortal53/352fda2D01d339306e03
[CustomEditor(typeof(RectTransform))] public class MyTest : DecoratorEditor { public MyTest(): base("RectTransformEditor"){} public override void OnInspectorGUI () { base.OnInspectorGUI (); if(GUILayout.Button("Adding this button")) { Debug.Log("Adding this button"); } } }
理论上unity提供的每一个脚本都有一个 XXXEditor 类 , 用来绘制它的面板。(本文用到的就是 RectTransformEditor)如果你不确定可以去我反编译的代码里面去找。https://bitbucket.org/xuanyusong/unity-decompiled
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 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 EditorInstance.RequiresConstantRepaint (); } public override bool UseDefaultMargins () { return EditorInstance.UseDefaultMargins (); } }
版本: unity5.3.3
相关文章推荐
- 【Unity】2.6 游戏视图(Game)
- 【Unity】2.5 场景视图(Scene)
- 【Unity】2.4 层次视图(Hierarchy)
- 【Unity】2.3 项目浏览器和资源的组织
- Unity3d BTDF实时折射模拟有粗糙度的半透明物体
- Unity3d BTDF实时折射模拟有粗糙度的半透明物体
- 最新Unity5.3.4p1&4.7.1f1破解!
- Unity Shaders and Effects Cookbook (2-6) 在 C# 代码中创建 Texture2D 并赋值给 Shader
- C#的Socket编程基础——Unity的简单聊天室
- UnityNGUI序列帧动画代码
- 详解MVP矩阵之ViewMatrix
- 【翻译】 Unity3D VR 教程:1.VR概述
- Unity小知识随手记
- Unity UGUI实现图文混排
- Unity UGUI实现图文混排
- unity3d 代码改变贴图压缩格式
- [置顶] Unity加载本地文件夹中的所有文件
- Unity3D嵌入WPF教程
- Unity 5.3 官方VR教程(—)VR综述
- Unity和Android交互