zoukankan      html  css  js  c++  java
  • Unity编辑器扩展

    编辑器简介:Unity支持扩展编辑器,扩展编辑器的代码要放入Editor文件夹中,Editor文件夹在项目打包时,是不会被打包的

    1:使用MenuItem添加菜单栏按钮:MenuItem是引用UnityEditor命名空间的

    public class AddTools  {
        [MenuItem("Assets/Test1",false,10)]
        static void test1()//必须为静态函数
        {
            Debug.Log("test1");      
        }
    }

    2:MenuItem的路径设置和显示的顺序设置,MenuItem有三个参数,第三个参数是设置按钮显示的先后顺序的。按钮显示一般以11为一个组,参数相差11就不是一个组了。

    [MenuItem("Assets/test1",false,1)]

    [MenuItem("Assets/test2",false,12)]这两个参数相差11,text1按钮在text2前面显示,text1和text2不是在同一个组。

     [MenuItem("Assets/tab1",false,0)]
        static void tab()
        {
            //这个静态方法是实现上面设置的按钮的功能的
        }
        [MenuItem("Assets/tab2", false, 11)]
        static void tab1()
        {
            //这个静态方法是实现上面设置的按钮的功能的
        }


    3:给组件或脚本的右键菜单添加按钮,去实现一些功能。

    [menuitem("CONTEXT/组件或脚本名/按钮名")]//往脚本的右键菜单中添加一个按钮实现某种功能

     [MenuItem("CONTEXT/text1/InitHealthAndSpeed1")]
        static void InitHealthAndSpeed()
        {
            //点击InitHealthAndSpeed1按钮就会执行这个静态方法
            Debug.Log("aa");
        }

    4:MenuCommand:是获取我们正在操作的组件或脚本的对象,拿到组件或脚本对象我们就可以对其进行操作。

    [MenuItem("CONTEXT/text1/InitHealthAndSpeed1")]
        static void InitHealthAndSpeed(MenuCommand cmd)
        {
            //点击InitHealthAndSpeed1按钮就会执行这个静态方法
            text1 ta1 = cmd.context as text1;//MenuCommand获取到正在操作的text1脚本组件
            ta1.a = 10;//对组件的内容进行修改
            Debug.Log(ta1.a);
        }

    5:Selection:获取unity中的一些物体对象。

       Selection.activeGameobject//获取Inspector面板中被选中的游戏物体,只能返回选中的一个物体对象,选中多个对象,只会得到第一个对象

        Selection.activeTransform//获取Inspector面板中被选中游戏物体的Transform组件,只能返回一个一个物体的Transform组件。选中多个对象,只会得到第一个对象

        selection.Objects//获取所有选中物体,包括Script scene 的所有资源呢

        selection.activeObject//只能获取一个被选中的资源,资源是可以是任何物体

        Selection.gameObjects//获取所有选中的Gameobject对象

        Selection.transform//获取所有被选中的游戏对象的transfoem属性

       

     GameObject go = Selection.activeGameObject;//获取被选中的一个物体对象,获取的只能是游戏对象
            Transform go1 = Selection.activeTransform;//获取被选中的一个物体的Transform组件,获取的只能是游戏对象
            GameObject[] go2 = Selection.gameObjects;//获取所哟被选中的游戏对象
           
            Transform[] go4 = Selection.transforms;//获取所哟被选中的游戏对象的transform属性
            object[] go3 = Selection.objects;//获取Unity中所有被选中的资源,资源可以是任何种类的
            object go5 = Selection.activeObject;//只能获取Unity中所有种被选中资源的一个,资源可以是任何种类的

    6:编写一个删除物体按钮,在物体被删除之后是可以撤销这个删除操作的。

         一般我们自己删除物体操作是无法撤回的,系统的删除物体的按键,删除的物体是可以撤销删除的操作的。因为系统的删除操作在删除之前会把删除操作的记录注册到内存中,物体并没有真正被删除,我们自己写的删除按钮也可以把删除的记录注册到内存中,这样我们自己写的删除操作也是可以撤销的

    Undo.DestoryObjectImmediate(gameobject)//利用Undo把删除操作注册到内存中

    在编辑器的脚本中删除物体使用DestoryImmediate(gameobject)这个API

      [MenuItem("Assets/tab1",false,0)]
        static void tab()
        {
            //这个静态方法是实现上面设置的按钮的功能的
          
            GameObject go = Selection.activeGameObject;//获取被选中的一个物体对象,获取的只能是游戏对象
             Undo.DestroyObjectImmediate(go);//把删除操作注册要内存中,按ctrl +z可以取消删除
            
          
        }

     7:给我们自己写的按钮添加快捷键

        自己设置快捷键时:%代表ctrl  #代表shift  &代表alt

        

    [MenuItem("Assets/tab2 %t", false, 11)]//给Tab2按键设置Ctrl +t为tab2按钮的快捷键
        static void tab1()
        {
           }

    设置的快捷键要与前面的按钮名空一格。如果只用一个按键作为快捷键则要在按键前加一个下划线

    [MenuItem("Assets/tab2 _t", false, 11)]
        static void tab1()
        {
                }

    8:在编辑器上的按钮可能只能作用一些物体,对另一些物体是不适用,当选中的是不适用的物体时,这个按钮是禁用的。这里需要使用menuitem的第二个参数,来判断这个按钮是否启用

    这两个Maneitem是配合使用的,false之前的true是判断按钮能按下的条件的,在返回true时,按钮就会被起用

    [menuitem("assets/a",true,1)]

    static bool delect()

    {

      判断是否满足条件,满足返回true,则按钮可以点击

      不满足就返回false 按钮被禁用

    }

    [menuitem("assets/a",false,1)]

    static void delect1()

    {

    //执行自定义按钮的功能

    }

     [MenuItem("Assets/tab1", true, 0)]
        static bool tab2()
        {
            if (Selection.activeGameObject == null)//判断是否选中物体
    
            {
                return false;
            }
            else
            {
                return true;//选中物体返回true,启用tab1按钮组件
            }
        }
    
        [MenuItem("Assets/tab1",false,0)]
        static void tab()
        {
            //这个静态方法是实现上面设置的按钮的功能的
          
            GameObject go = Selection.activeGameObject;//获取被选中的一个物体对象,获取的只能是游戏对象
          //  GameObject.DestroyImmediate(go);//删除这个对象
            Undo.DestroyObjectImmediate(go);//把删除操作注册要内存中,按ctrl +z可以取消删除
            
          
        }

    mainitem中的True 和false 相互配合,来实现按钮选择性实现

    9:[contextMenu(“按键名”)]给自定义的脚本添加按键   [contextMenuitem("按键名","要执行的方法名")]给自定义的脚本属性添加按键

    contextMen和contextMenuitem标签不需要再编辑器的脚本中使用,可以直接再要添加按钮的脚本中使用,生成自己定义的按钮

    public class text1 : MonoBehaviour {
        [ContextMenuItem("addcount", "Add")]//直接在自定义脚本的属性a添加按钮,按钮执行的功能是执行add方法,按钮名是addCount
        public int a = 0;
        void Add()
        {
            a += 10;
            print(a);
        }
        [ContextMenu("TestButton")]//直接在自定义的脚本添加右键按钮TestButton,执行的功能是标签下面的方法
    
        void Onbutton()
        {
            print("a");
        }
    }

     10:创建一个对话框,对话框中读取的数据是从指定的脚本中读取的。对话框只能从继承ScripttableWizard类的类中读取数据,创建对话框的脚本也是编辑器脚本

           创建对话框的函数是scriptTableWrizard.DisplayWizard<存储数据的脚本,脚本要继承ScripttableWizard的类>("对话框的名称");

    using UnityEditor;
    public class CreateEdior :ScriptableWizard {
    
        [MenuItem("Assets/tab3",false,2)]//创建tab3按钮
        static void tab3()
        {
            ScriptableWizard.DisplayWizard<CreateEdior>("修改数据");//创建对话框,读取CreateEditor脚本的数据,文本框的名字为“修改数据”
        }
        public float speed;//CreateEditor脚本中的数据
        public int index;
        [MenuItem("Assets/tab4", false, 3)]//创建tab4按钮
        static void tab4()//创建对话框
        {
            ScriptableWizard.DisplayWizard<stab>("修改数据");
        }
    
    }
    public class stab:ScriptableWizard//文本框要交互的数据
    {
        public int a = 10;
        public int b = 19;
    }

    11:在创建的对话框中创建按钮,触发点击事件  ScriptTableWizard.DisplayWizard<存储数据的脚本,脚本要继承ScripttableWizard的类>("对话框的名称",“在对话框中创建的按钮名”)  这个按钮是绑定固定的方法 OnWizardCreate(),按钮被点击时触发这个方法

     public float speed;//CreateEditor脚本中的数据
        public int index;
        [MenuItem("Assets/tab3",false,2)]//创建tab3按钮
        static void tab3()
        {
            ScriptableWizard.DisplayWizard<CreateEdior>("修改数据","CreatButton");//创建对话框,读取CreateEditor脚本的数据,文本框的名字为“修改数据”
        }
        void OnWizardCreate()//对话框的按钮被点击时,触发这个方法
        {
            GameObject[] enemy = Selection.gameObjects;//获取所有被选中的对象
            foreach (var go in enemy)
            {
                if(go.transform.tag=="enemy")//获取选中标签为enemy的物体
                {
                    text1 text2 = go.GetComponent<text1>();//获取他们的text1脚本
                    text2.a = index;//用对话框的index值修改获取对象的脚本值
                }
            }
        }
       

     12:OnWizardUpdate()  和 OnSelectionChange()

     OnWizardUpdate()我们修改对话框中的字段或值时,就会调用这个方法

     OnSelectionChange()当我们更改选中的对象时,就会触发这个方法

      /// <summary>
        /// 替换被选中的对象时就会触发这个方法
        /// </summary>
        void OnSelectionChange()
        {
            Debug.Log(Selection.activeGameObject.name);//打印出被选中的一个游戏对象的名字
        }
        /// <summary>
        /// 对话框打开时触发这个方法,对话框中字段一改动就执行该方法
        /// </summary>
        void OnWizardUpdate()
        {
            Debug.Log(index);
        }

    13: otherButton,创建对话框的第二个按钮,OnwizardotherButton这个方法绑定这个按钮,对话框的第一个按钮在按下之后对话框就会关闭,但第二个按钮按下对话框不会关闭

    创建第二个按钮  ScriptTableWiazrd.DisplayWiazid<script>("对话框的名字",“第一个按钮名”,“第二个按钮名”)

    第一个按钮名 触发的方法OnWiazrdCreate()

    第二个按钮名 触发的方法OnWiazrdotherButton()

     [MenuItem("Assets/tab3",false,2)]//创建tab3按钮
        static void tab3()
        {
            ScriptableWizard.DisplayWizard<CreateEdior>("修改数据","CloseButton","otherButton");//创建对话框,读取CreateEditor脚本的数据,文本框的名字为“修改数据”
        }
        void OnWizardCreate()//对话框的CloseButton按钮被点击时,触发这个方法
        {
            Debug.Log("对话框已关闭");
        }
        void OnWizardOtherButton()//对话框的otherButton按钮被点击时,触发这个方法
        {
            GameObject[] enemy = Selection.gameObjects;//获取所有被选中的对象
            foreach (var go in enemy)
            {
                if (go.transform.tag == "enemy")//获取选中标签为enemy的物体
                {
                    text1 text2 = go.GetComponent<text1>();//获取他们的text1脚本
                    Undo.RecordObject(text2, "change");//把text2这个类的数据存储起来,类修改后,可以ctrl +z恢复到现在记录的类的数据
                    text2.a = index;//用对话框的index值修改获取对象的脚本值
                }
            }
        }
       

    14:记录一个类的数据,在类被修改后,可以用Ctrl +z撤销修改类中数据的操作 Undo.Recordobject(类名,“这个操作在内存中的名字,是自己随便起的”)

    void OnWizardCreate()//对话框的按钮被点击时,触发这个方法
        {
            GameObject[] enemy = Selection.gameObjects;//获取所有被选中的对象
            foreach (var go in enemy)
            {
                if(go.transform.tag=="enemy")//获取选中标签为enemy的物体
                {
                    text1 text2 = go.GetComponent<text1>();//获取他们的text1脚本
                    Undo.RecordObject(text2, "change");//把text2这个类的数据存储起来,类修改后,可以ctrl +z恢复到现在记录的类的数据
                    text2.a = index;//用对话框的index值修改获取对象的脚本值
                }
            }
        }

    15:对话框的提示字符和错误警告提示字符     helpString 提示字符串    errorString 错误提示符

    16:ShowNotification显示提示信息。这个函数只能在对话框中显示提示信息。

         

     void OnWizardOtherButton()//对话框的otherButton按钮被点击时,触发这个方法
        {
            int a = 0;
            GameObject[] enemy = Selection.gameObjects;//获取所有被选中的对象
            foreach (var go in enemy)
            {
                a++;
                if (go.transform.tag == "enemy")//获取选中标签为enemy的物体
                {
                    text1 text2 = go.GetComponent<text1>();//获取他们的text1脚本
                    Undo.RecordObject(text2, "change");//把text2这个类的数据存储起来,类修改后,可以ctrl +z恢复到现在记录的类的数据
                    text2.a = index;//用对话框的index值修改获取对象的脚本值
                }
            }
            ShowNotification(new GUIContent(Selection.objects.Length + "个物体值被修改"));//按下第二个按钮,会显示提示信息
        }

    17:使用EditorPerfabs保存弹出窗口中修改的数据

    保存int 类型的值 Editorperfabs.setint("保存到这个字段",要被保存的字段)

    调用这个被保存的Int 类型的值 Editorperfabs.GetInt("保存到的新字段",第一次打开这个对话框的显示值)

     void OnEnable()
        {
         index= EditorPrefs.GetInt("IndexKey", index);//在窗口被打开时,第一次使用index赋值给index,以后再打开就把保存的indexkey值赋予index,这样就完成保存每次修改的Index的值
        }
     EditorPrefs.SetInt("IndexKey", index);//把面板中修改的index值,保存到IndexKey中

    18:显示进度条,使用EditorUtility.DisplayProgressBar("标题",“下标题”,进度),关闭EditorUtility.clearProgressBar()进度条

     foreach (var go in enemy)
            {
                a++;
                if (go.transform.tag == "enemy")//获取选中标签为enemy的物体
                {
                    text1 text2 = go.GetComponent<text1>();//获取他们的text1脚本
                    Undo.RecordObject(text2, "change");//把text2这个类的数据存储起来,类修改后,可以ctrl +z恢复到现在记录的类的数据
                    text2.a += index;//用对话框的index值修改获取对象的脚本值
                    EditorPrefs.SetInt("IndexKey", index);//把面板中修改的index值,保存到IndexKey中
                }
                EditorUtility.DisplayProgressBar("进度", a + "/" + enemy.Length, a / enemy.Length);//显示修改数值的进度
            }
            EditorUtility.ClearProgressBar();//修改数值结束,关闭进度条

     20:创建自定义的窗口 创建自定义的窗口脚本继承EditorWindows脚本,用MyWindow脚本对象的show方法,实现创建窗口

    using UnityEditor;
    
    
    public class WindowEdior : EditorWindow {
        //脚本继承editorWindow
        [MenuItem("windows/createWindows",false,1)]//创建createwindows按键,实现创建窗口的功能
        static void create()
        {
            WindowEdior window = EditorWindow.GetWindow<WindowEdior>();//创建窗口
            window.Show();//显示窗口
        }
        
    }
  • 相关阅读:
    Python-24-多线程
    RT-Thread动态内存堆的使用
    Linux编程概念
    Linux_C语言基础
    文件IO_open(),read(),write(),lseek(),close()
    SourceTree跳转注册的方法
    Linux——软件安装
    初学DOM树解析xml文件
    简单json语句转化为map保存
    最大独立集求解
  • 原文地址:https://www.cnblogs.com/zhangyang4674/p/10976556.html
Copyright © 2011-2022 走看看