Unity编辑器扩展

发表于2018-03-21
评论0 3k浏览
Unity拥有非常丰富的扩展编辑器接口,Uity通过提供EditorScript API 的方式为开发者提供了方便强大的编辑器扩展途径,如果掌握了可以帮助大家编写一些工具来提高效率,甚至可以自制一些小的插件应用的项目工程中去下面就和大家介绍下常用的编辑器扩展功能。

【简单按钮】

在Assets文件夹下新建一个Editor文件夹
当打包时Editor文件下的内容不会打包进去
接下来在Editor下新建一个自定义名为HelloWord的C#脚本
添加头文件
using UnityEditor;  
using UnityEngine;  

首先做一个简单的插件按钮
//按钮位置      是否有效    优先级  
    [MenuItem("GameObject/HelloWord",false,12)]  
    public static void helloword()  
    {  
        Debug.Log("helloword");  
    }

【组件按钮】

在组件下右键点击显示自定义的按钮
同样在HelloWord.cs文件下添加如下代码
//组件右键显示按钮  
    //CONTEXT   组件名     按钮名  
    [MenuItem("CONTEXT/TextScript/InitValue")]  
    public static void InitValue(MenuCommand cmd)//将选中的组件传过来  
    {  
        //TextScript组件是挂载在对象上的组件  
        TextScript text = cmd.context as TextScript;  
        text.value = 10;  
    }  
这样当我们右点击鼠标,点击InitValue按钮,将执行以上函数

【Selection】

当在Hierarchy窗口下选择游戏对象后,操作Selection类
//选择游戏对象  
    //并且记录删除操作  
    [MenuItem("GameObject/Delete_1",false,13)]  
    public static void Delete_1()  
    {  
        //获取选择的个数  
        Debug.Log(Selection.objects.Length);  
        //在选取的游戏对象中第一个被选择的对象  
        Debug.Log(Selection.activeObject.name);  
        foreach (Object obj in Selection.objects)  
        {  
            //将对象之间删除,不能撤销  
            GameObject.DestroyImmediate(obj);  
            //使用Undo可以撤销  
            Undo.DestroyObjectImmediate(obj);  
        }  
    }  

【注册快捷键】
//注册快捷键  
    //  %表示ctrl     #表示shift    &表示alt  
    //路径和注册符号需要用空格隔开  
    //当注册符号为单个字符时,用_开头。如:_t表示快捷键t  
    [MenuItem("GameObject/MyKey #a",false,14)]  
    public static void MyKey()  
    {  
        Debug.Log("myKey");  
    }  

【取消按钮】
//参数二   是否有效显示  
    [MenuItem("GameObject/Delete_2",true,15)]  
    public static bool Delete_2()  
    {  
        if (Selection.objects.Length > 0)  
        {  
            //有效  
            return true;  
        }  
        //无效  
        return false;  
    }  
    [MenuItem("GameObject/Delete_2", false, 15)]  
    public static void Delete_3()  
    {  
        foreach (Object obj in Selection.objects)  
        {  
            Undo.DestroyObjectImmediate(obj);  
        }  
    }  

【ContextMenu】

在【组件按钮】下介绍的是在其他脚本控制该组件代码
另外还有一种方式就是在自身组件的代码里添加按钮控件
TextScript.cs
using UnityEngine;  
using System.Collections;  
public class TextScript : MonoBehaviour   
{  
    public int value = 0;  
    //在组件属性选项中右键  
    //选项名   函数名  
    [ContextMenuItem("Set False","ChangeFalse")]  
    [ContextMenuItem("Set True", "ChangeTrue")]  
    public bool isRun = true;  
    void ChangeFalse()  
    {  
        this.isRun = false;  
    }  
    void ChangeTrue()  
    {  
        this.isRun = true;  
    }  
    //直接在函数里面设置按钮  
    //点击函数,将会运行函数  
    //函数不必定义为静态函数  
    [ContextMenu("SetValue")]  
    public void SetValue()  
    {  
        this.value = 100;  
    }  
}  

【对话框】

在一些时候,我们需要在批量对选择的游戏对象上进行数据更改
这是我们可以添加一个对话框,对话框提供选一些选项,确定里面的数据值后,对选中的游戏对象数值进行更改
以下是创建一个对话框的示列代码:
using UnityEngine;  
using System.Collections;  
using UnityEditor;  
public class SelfDialog : ScriptableWizard   
{  
    [MenuItem("Tool/CreateSelfDialog")]  
    public static void Create()  
    {  
        ScriptableWizard.DisplayWizard<SelfDialog>("helloword","Change And Close","Change");  
    }  
    public int changeStartHealthValue = 10;  
    public int changeSinkSpeedValue = 1;  
    const string changeStartHealthValueKey = "SelfDialog.changeStartHealthValue";  
    const string changeSinkSpeedValueKey = "SelfDialog.changeSinkSpeedValue";  
    //当窗口被创建出来的时候调用的  
    void OnEnable()  
    {  
    }  
    //检测create按钮的点击  
    //当点击后同时会自动关闭该窗口  
    void OnWizardCreate()  
    {  
        Debug.Log(changeStartHealthValue + "," + changeSinkSpeedValue);  
    }  
    //当点击后不会自动关闭该窗口  
    void OnWizardOtherButton()  
    {  
        OnWizardCreate();  
        ShowNotification(new GUIContent("完成"));  
    }  
    //当前字段值修改的时候会被调用  
    void OnWizardUpdate()  
    {  
        EditorPrefs.SetInt(changeStartHealthValueKey, changeStartHealthValue);  
        EditorPrefs.SetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);  
    }  
    //当选择的游戏对象发生改变后,将调用该函数  
    void OnSelectionChange()  
    {  
        OnWizardUpdate();  
    }  
}  

【进度条】

进度条的作用不多说,直接上创建代码(简单模拟下):
using UnityEngine;  
using System.Collections;  
using UnityEditor;  
public class SelfProgressBar :MonoBehaviour  
{  
    float timer = 0;  
    int count = 0;  
    void Start()  
    {  
        EditorUtility.DisplayProgressBar("进度", "0/10" + " 完成修改值", 0);  
    }  
    void Update()  
    {  
        timer+=Time.deltaTime;  
        if (timer>=1.0f)  
        {  
            timer = 0.0f;  
            count++;  
            EditorUtility.DisplayProgressBar("进度", count+"/10" + " 完成修改值", (float)count/10);  
        }  
        if (count >= 10)  
        {  
            EditorUtility.ClearProgressBar();  
        }  
    }  
}  

【窗口】

接下来介绍如何创建一个像Unity下的Hierachy和Projects类似的窗口
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using UnityEditor;  
public class MyWindow : EditorWindow  
{  
    [MenuItem("Window/show mywindow")]  
    static void ShowMyWindow()  
    {  
        MyWindow window = EditorWindow.GetWindow<MyWindow>();  
        window.Show();  
    }  
    private string name = "";  
    void OnGUI()  
    {  
        GUILayout.Label("这是我的窗口");  
        name = GUILayout.TextField(name);  
        if (GUILayout.Button("创建"))  
        {  
            GameObject go = new GameObject(name);  
            Undo.RegisterCreatedObjectUndo(go, "create gameobject");  
        }  
    }  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引