Unity 編輯器(UnityEditor)

<small>前幾天開始準備看源碼,結合自己工作使用Lua,想看sLua框架源碼,但是Lua確實不太熟悉,于是還是選擇C#,打算看NGUI的源碼(因為工作中也有用到)。
自己看源碼經驗不是很多,有些感覺無從下手,因為里面的代碼跳轉太多了,打算先看看NGUI的編輯器是怎么做出來的,于是開始研究Unity的編輯器制作。</small>

一、引言

Unity允許開發者自己制定編輯器,這也給了我們很多的方便,例如:要打包AssetBundle的時候,我們可以自己寫一個菜單項點擊進行我們所想要的打包。還有一些時候我們可以創建一個窗口完成Unity并沒有提供支持的編輯。

二、UnityEditor相關類
  • Editor:編輯器
  • EditorWindow :編輯窗口(類似Console就是一個編輯窗口),其中初始化方法應為static,否則在Unity編輯過程中不能找到匹配的選項
  • GenericMenu :編輯窗口中菜單
  • EditorGUILayout :編輯窗口中的界面布局類
  • MenuItem屬性:添加菜單項在控制面板主菜單和檢視面板上下文菜單
  • GUILayout : 可以在編輯窗口用
  • MenuCommand :用于提取上下文菜單項。MenuCommand對象被傳遞給自定義菜單項功能使用菜單項定義的屬性。
  • Event : 事件,Event.current.可以獲取到當前的系統處理的事件
    <strong>注:編輯器腳本需要放在Editor文件夾下,在進行Unity編輯的時候生效,Unity會把Editor下的腳本認為是Editor腳本,不允許掛載在游戲物體上。</strong>

三、制作菜單

3.1創建主菜單下的菜單項(MenuItem)

終于到了令人期待的動手時刻啦,現來個簡單的


主菜單下的編輯菜單
    /*
     * static void MenuItem (itemName : string, isValidateFunction : bool,  priority : int) : MenuItem
     * itemName : 菜單名,以"/"分級,第一個是和主菜單同級的位置,該級菜單不能以中文命名,后面的都可以用中文
     * isValidateFunction : 這個參數標志是否是驗證函數
     * priority : 優先級,值越小,在菜單中越靠上
     */

    //主菜單下的一級菜單menu1
    [MenuItem("Menu/menu1" , false, 1)]
    static public void Menu1()
    {
        Debug.Log("menu1");
    }

    //主菜單下的二級菜單menu2
    [MenuItem("Menu/menu2/menu2", false, 2)]
    static public void Menu2()
    {
        Debug.Log("menu2/menu2");
    }

<strong>在寫編輯器腳本的時候記得要using UnityEditor</strong>

3.2 特定情況下可以使用的菜單

弄完上面這菜單,只有一句話可以說:“這也真是夠爛的”。不過畢竟是最簡單的菜單,接下來,我們慢慢優化,學習嘛,總有個循序漸進的過程。
下面,我們來給菜單添加一個特定情況下使用的功能,例如,我們讓它只在我們選中了某種特定游戲物體的時候才讓他顯示,讓它可以被點擊。

不能點擊
//主菜單下的一級菜單menu1
    [MenuItem("Menu/menu1" , false, 1)]
    static public void Menu1()
    {
        Debug.Log("menu1");
    }

    //這是Menu/menu1的驗證函數,當返回true時,menu1顯示可點,否則不能點
    [MenuItem("Menu/menu1", true)]
    [MenuItem("Menu/menu1", true)]
    static public bool ShowMenu1()
    {
        GameObject selectObj = Selection.activeGameObject;
        return selectObj != null && selectObj.tag == "Display";
    }
3.3 給自定義MenuItem綁定快捷鍵

老感覺MenuItem就前面這一點東西不好用,還是有快捷鍵的好,方便多了。
這可能是學習MenuItem最簡單的一個步驟了,一行代碼都不需要,只需要幾個字符,我剛找到方法的時候都不敢相信!!!

綁定快捷鍵

解釋和代碼都在下面了:

    //主菜單下的二級菜單menu2
    /*
     * _%H 表示快捷鍵為ctrl + H
     * 創建快捷鍵方式 : 在對應的MenuItem后面以" _"開頭,后面添加快捷鍵標志
     * 快捷鍵標志規則 : 
     *      % = ctrl 
     *      # = Shift
     *      & = Alt 
     *      F1…F2 = F... 
     *      LEFT/RIGHT/UP/DOWN = 上下左右 
     *      HOME, END, PGUP, PGDN = 鍵盤上的特殊功能鍵
     */
    [MenuItem("Menu/menu2/menu2 _%H", false, 2)]
    static public void Menu2()
    {
        Debug.Log("menu2/menu2");
    }
3.4 添加MenuItem到對應Insecptor面板
Insecptor中的Camera上添加菜單
    /*
     * 在Inspector中對應的組件中右鍵中添加菜單
     * MenuItem("CONTEXT/[ComponentName]/[DisplayName]")
     * static void FunctionName(MenuCommand command) { //function body code }
     */
    [MenuItem("CONTEXT/Camera/Item")]
    static public void Item(MenuCommand command)
    {
        //command.context獲取對應Object
        Camera camera = command.context as Camera;
        Debug.Log(string.Format("light info : name = {0}", camera.name));
    }

四、創建編輯窗口

前面了解了編輯菜單的制作,現在,我們來學習下編輯窗口怎么做。
其實,一個編輯窗口就是一個EditorWindow,翻譯過來也就是編輯窗口啦。
首先,創建一個腳本,繼承EditorWindow,也就是創建了一個編輯窗口了,只不過沒有顯示罷了。
<strong>再次聲明:我們這些腳本都是放在Editor文件夾下的,我們的腳本也都是繼using UnityEditor才能有效編譯的。</strong>

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.Tizen;

public class EditWindow : EditorWindow
{
    static string myString = "Hello World";
    bool groupEnabled;
    bool myBool = true;
    float myFloat = 1.23f;
    static GenericMenu menu;
    
    //初始化,也就是一個MenuItem,當點擊時調用Init()
    [MenuItem("Window/EditWindow _%&#B")]
    static void Init()
    {
        Debug.Log("init");
        // Get existing open window or if none, make a new one:
        GetWindow(typeof(EditWindow));   //獲取到窗口,并且顯示
        //實例化并且設置menu
        menu = new GenericMenu();   //初始化menu,但是沒有顯示
        menu.AddItem(new GUIContent("MenuItem1"), false, Callback, "item 1");
        menu.AddItem(new GUIContent("MenuItem2"), false, Callback, "item 2");
        menu.AddSeparator("");
        menu.AddItem(new GUIContent("SubMenu/MenuItem3"), false, Callback, "item 3");
    }
    
    //通過GUI渲染,每幀調用
    void OnGUI()
    {
        //創建要顯示在編輯窗口的內容
        GUILayout.Label("Base Settings", EditorStyles.boldLabel);
        myString = EditorGUILayout.TextField("Text Field", myString);
        EditorGUILayout.Space();    //空行:間隙
        //ToggleGroup
        groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);
        myBool = EditorGUILayout.Toggle("Toggle", myBool);
        myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
        myString = EditorGUILayout.TextField("Field", myString);
        EditorGUILayout.EndToggleGroup();

        EditorGUILayout.BeginVertical("Button");
        GUILayout.Label("I'm inside the button");
        GUILayout.Label("So am I");
        EditorGUILayout.EndVertical();

        Event currentEvent = Event.current;
        Rect contextRect = new Rect(0, 200, 100, 100);
        //EditorGUI.DrawRect(contextRect, Color.green);
        EditorGUI.LabelField(contextRect, "Hello World Text");

        if (currentEvent.type == EventType.MouseDown)   //點擊事件發生在當前EditorWindow上
        {
            Vector2 mousePos = currentEvent.mousePosition;
            if (contextRect.Contains(mousePos)) //點在矩形范圍內
            {
                menu.ShowAsContext();   //顯示menu
                currentEvent.Use();
            }
        }
    }

    //回調
    static void Callback(object obj)
    {
        Debug.Log("Selected: " + obj.ToString());
    }
}

這就是創建一個面板的代碼了,可以直接復制到自己的工程中,創建如下窗口


MenuItem

窗口

對于里面的OnGUI代碼,就是用到UnityEditor相關類中的一些類了,大家可以研究下。
<strong>最后,文章就到這了,文筆有限,望大家見諒。
歡迎各路英雄互相討論學習。</strong>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容