Unity编辑器扩展-基本界面编写

一.在编辑器上增加一个MenuItem


先进行第一步,给编辑器加个菜单,通过[MenuItem("AXX/BXX")]就可以在编辑器的上边菜单栏增加一个下拉菜单AXX,并增加一个按钮BXX。只要把这句话写在我们定义的函数上方就可以,然后我们点击这个按钮,就会调用这个我们自定义的函数。不过有一点一定要记住,这个函数要是static的!(想一想就可以知道是为什么,编辑器没有必要搞粗一个对象之类的,因为我们要调用的只是这个方法)例如:

    using UnityEngine;  
    using UnityEditor;  
    using System.Collections;  
      
    public class EditorTest  
    {  
        [MenuItem("MyTools/EditorTest")]  
        public static void ConfigDialog()  
        {  
            Debug.Log("EditorTest ToolButton is pressed!");  
        }  
    }  

我们的编辑器就多了这样的一个工具选项MyTools,点击出现了EditorTest下拉菜单,再点击按钮就会输出Log了,如下图所示:



二.创建一个对话框


如果我们嫌这个一个下拉菜单不爽,那我们就可以创建一个对话框,然后就可以在对话框里放更多的按钮或者一些工具条来调节相关内容,下面看一下在Unity编辑器中对话框的创建以及使用。
    using UnityEngine;  
    using UnityEditor;  
    using System.Collections;  
      
    //typeof(编辑器类名),继承EditorWindow  
    [CustomEditor(typeof(EditorTest))]  
    public class EditorTest : EditorWindow  
    {  
        //通过MenuItem按钮来创建这样的一个对话框  
        [MenuItem("MyTools/EditorTest")]  
        public static void ConfigDialog()  
        {  
            //GetWindow创建  
            EditorWindow.GetWindow(typeof(EditorTest));  
        }  
      
        public UnityEngine.Object go = null;  
      
        //对话框中的各种内容通过OnGUI函数来设置  
        void OnGUI()  
        {  
            //Label  
            GUILayout.Label("Label Test", EditorStyles.boldLabel);  
            //通过EditorGUILayout.ObjectField可以接受Object类型的参数进行相关操作  
            go = EditorGUILayout.ObjectField(go, typeof(UnityEngine.Object), true);  
            //Button  
            if (GUILayout.Button("Button Test"))  
            {  
                Debug.Log(go.name);  
            }  
        }  
         
    }  



结果如下:

通过这样的一个脚本,我们就可以在Unity中创建一个对话框,然后再在对话框里进行进一步的设置。

三.扩展Inspector面板


这一部分比较重要,也是我们最经常使用的部分。

1.ContextMenu

比如我们写了个脚本,但是有一些函数需要调用触发,测试的时候又不方便,一种方法是重写MonoBehaviour类的OnGUI方法,但是这种方法也比较笨,要写好多代码,除非真机调试的时候,没有办法才这样做,我们可以通过一种更简单的方式来实现。

我们如果想直接调用我们继承MonoBehaviour的类的某个函数,只需要在函数上加上[ContextMenu(“函数名称”)]即可:
  1. [ContextMenu("Context Menu Test")]  
  2.     void OnTest()  
  3.     {  
  4.         Debug.Log("Context Menu is called");  
  5.     }  
结果如下:

通过ContextMenu,我们可以更方便地测试我们的脚本,随时通过编辑器调用我们的函数,而不用再去其他外层函数。

2.自定义inspector面板


有时,我们需要更加方便美术或者策划来编辑对象属性,这时候,我们就可以通过自定义Inspector面板来进行控制:

    using UnityEngine;  
    using UnityEditor;  
    using System.Collections;  
      
    //typeof中参数即为我们需要定义Inspector面板的组件  
    [CustomEditor(typeof(CustomEditorTest))]  
    public class TestCustomEditor : Editor {  
      
        CustomEditorTest script;  
      
        public override void OnInspectorGUI()  
        {  
            base.OnInspectorGUI();  
            //将target转化为我们需要的脚本  
            script = target as CustomEditorTest;  
            //增加一个按钮  
            if (GUILayout.Button("Test Button"))  
            {  
                //可以直接访问CustomEditorTest类的内容  
                script.Test(script.num);  
            }  
        }  
    }  


结果:



四.编辑器插件常用函数

1.AssetDatabase.CreateAsset可以帮住你从资源目录中创建一个资源实例。
2.Selection.activeObject返回当前选中的对象。 
3.EditorGUIUtility.PingObject用来实现在Project窗口中点击某一项的操作。
4.Editor.Repaint用来重绘界面所有的控件。
5.XXXImporter用来设置某种资源的具体导入设置(例如在某些情况下你需要设置导入的贴图为可读的)。 
6.EditorUtility.UnloadUnusedAssets用于释放没有使用的资源,避免你的插件产生内存泄漏。 
7.Event.Use用来标记事件已经被处理结束了。 
8.EditorUtility.SetDirty用来通知编辑器数据已被修改,这样在下次保存时新的数据将被存储。

五.一些常用的Inspector属性设置

    using System;  
    using UnityEngine;  
      
    public class Test : MonoBehaviour  
    {  
        #region 编辑Inspector视图  
        /// <summary>  
        /// 只能输入 0-1的值  
        /// </summary>  
        [Range(0f, 1f)]  
        public float tRange = 1f;  
      
        /// <summary>  
        /// 输入时的提示  
        /// </summary>  
        [Tooltip("Tooltip_test")]  
        public float tTooltip = 1f;  
      
        /// <summary>  
        /// 标头  
        /// </summary>  
        [Header("Header_test")]  
        public float tHeader = 1f;  
      
        /// <summary>  
        /// 距离上一行50px  
        /// </summary>  
        [Space(50)]  
        public float tSpace = 1f;  
      
        /// <summary>  
        /// 隐藏该属性(依然会被实例化)  
        /// </summary>  
        [HideInInspector]  
        public float tHideInInspector = 1f;  
     
        #endregion  
     
        #region 编辑MonoBehaviour功能  
        /// <summary>  
        /// 在标题栏Component中添加("Duan/AddComponentMenu_test")层级。  
        /// 点击将(Test)脚本绑定到当前选中的gameobject上。  
        ///(Test)脚本名必须与文件名一致,(单独的Class文件)。  
        /// </summary>  
        //[AddComponentMenu("Duan/AddComponentMenu_test")]  
        //public class Test : MonoBehaviour{}  
      
        /// <summary>  
        /// 在辑模式运行Update、FixedUpdate和OnGUI。  
        /// </summary>  
        //[ExecuteInEditMode]  
        //public class Test : MonoBehaviour{}  
      
        /// <summary>  
        /// 强制要求该脚本的gameobject必须同时绑定了Rigidbody组件,如果没有则立即添加。  
        /// </summary>  
        //[RequireComponent(typeof(Rigidbody))]  
        //public class Test : MonoBehaviour{}  
      
        /// <summary>  
        /// 给当前脚本添加右键(或小齿轮)选项  
        /// 点击调用该方法。  
        /// </summary>  
        [ContextMenu("ContextMenu Test")]  
        public void mContextMenu()  
        {  
            Debug.Log("ContextMenu Test Log");  
        }  
      
        /// <summary>  
        /// 在标题栏中添加("Duan/MenuItem")层级。  
        /// 点击调用该方法。  
        /// 该方法必须是static的。  
        /// </summary>  
        [MenuItem("Duan/MenuItem")]  
        public static void tMenuItem()  
        {  
            Debug.Log("MenuItem Test Log");  
        }  
        #endregion   
     
        #region 编辑属性  
        /// <summary>  
        /// 标记一个变量或方法不会被序列化  
        /// </summary>  
        [NonSerialized]  
        public float tNonSerialized = 1f;  
      
        /// <summary>  
        /// 该类可以被序列化 (序列化就是把内存中对象以一种可以保存的形式保存起来。 )  
        /// </summary>  
        [Serializable]  
        public class Serializable{ }  
      
        /// <summary>  
        /// 强制序列化属性(Unity只序列化Public属性。序列化Private添加[SerializeField]。)  
        /// </summary>  
        [SerializeField]  
        private bool tSerializeField = true;  
        #endregion  
    }  


PS:转载于 http://blog.csdn.net/asd237241291/article/details/41696981

六.参考链接

http://blog.csdn.net/asd237241291/article/details/38235091

http://blog.csdn.net/kun1234567/article/details/19421471

http://blog.sina.com.cn/s/blog_471132920101n8cr.html

原文地址:http://blog.csdn.net/puppet_master/article/details/51012298

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值