<small>前幾天開始準(zhǔn)備看源碼,結(jié)合自己工作使用Lua反肋,想看sLua框架源碼踏施,但是Lua確實(shí)不太熟悉,于是還是選擇C#养距,打算看NGUI的源碼(因?yàn)楣ぷ髦幸灿杏玫剑?br> 自己看源碼經(jīng)驗(yàn)不是很多日熬,有些感覺無從下手,因?yàn)槔锩娴拇a跳轉(zhuǎn)太多了耘纱,打算先看看NGUI的編輯器是怎么做出來的毕荐,于是開始研究Unity的編輯器制作东跪。</small>
一、引言
Unity允許開發(fā)者自己制定編輯器虽填,這也給了我們很多的方便斋日,例如:要打包AssetBundle的時(shí)候墓陈,我們可以自己寫一個(gè)菜單項(xiàng)點(diǎn)擊進(jìn)行我們所想要的打包。還有一些時(shí)候我們可以創(chuàng)建一個(gè)窗口完成Unity并沒有提供支持的編輯兔港。
二仔拟、UnityEditor相關(guān)類
- Editor:編輯器
- EditorWindow :編輯窗口(類似Console就是一個(gè)編輯窗口),其中初始化方法應(yīng)為static科侈,否則在Unity編輯過程中不能找到匹配的選項(xiàng)
- GenericMenu :編輯窗口中菜單
- EditorGUILayout :編輯窗口中的界面布局類
- MenuItem屬性:添加菜單項(xiàng)在控制面板主菜單和檢視面板上下文菜單
- GUILayout : 可以在編輯窗口用
- MenuCommand :用于提取上下文菜單項(xiàng)。MenuCommand對象被傳遞給自定義菜單項(xiàng)功能使用菜單項(xiàng)定義的屬性蔫慧。
- Event : 事件,Event.current.可以獲取到當(dāng)前的系統(tǒng)處理的事件
<strong>注:編輯器腳本需要放在Editor文件夾下权薯,在進(jìn)行Unity編輯的時(shí)候生效,Unity會把Editor下的腳本認(rèn)為是Editor腳本盟蚣,不允許掛載在游戲物體上。</strong>
三刁俭、制作菜單
3.1創(chuàng)建主菜單下的菜單項(xiàng)(MenuItem)
終于到了令人期待的動手時(shí)刻啦牍戚,現(xiàn)來個(gè)簡單的
/*
* static void MenuItem (itemName : string, isValidateFunction : bool, priority : int) : MenuItem
* itemName : 菜單名如孝,以"/"分級,第一個(gè)是和主菜單同級的位置第晰,該級菜單不能以中文命名,后面的都可以用中文
* isValidateFunction : 這個(gè)參數(shù)標(biāo)志是否是驗(yàn)證函數(shù)
* priority : 優(yōu)先級品抽,值越小甜熔,在菜單中越靠上
*/
//主菜單下的一級菜單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>在寫編輯器腳本的時(shí)候記得要using UnityEditor</strong>
3.2 特定情況下可以使用的菜單
弄完上面這菜單腔稀,只有一句話可以說:“這也真是夠爛的”。不過畢竟是最簡單的菜單淡喜,接下來诵闭,我們慢慢優(yōu)化,學(xué)習(xí)嘛们镜,總有個(gè)循序漸進(jìn)的過程。
下面颈抚,我們來給菜單添加一個(gè)特定情況下使用的功能嚼鹉,例如,我們讓它只在我們選中了某種特定游戲物體的時(shí)候才讓他顯示匹舞,讓它可以被點(diǎn)擊线脚。
//主菜單下的一級菜單menu1
[MenuItem("Menu/menu1" , false, 1)]
static public void Menu1()
{
Debug.Log("menu1");
}
//這是Menu/menu1的驗(yàn)證函數(shù)浑侥,當(dāng)返回true時(shí),menu1顯示可點(diǎn)括丁,否則不能點(diǎn)
[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就前面這一點(diǎn)東西不好用伶选,還是有快捷鍵的好,方便多了构资。
這可能是學(xué)習(xí)MenuItem最簡單的一個(gè)步驟了肖卧,一行代碼都不需要,只需要幾個(gè)字符,我剛找到方法的時(shí)候都不敢相信?选>湫!
解釋和代碼都在下面了:
//主菜單下的二級菜單menu2
/*
* _%H 表示快捷鍵為ctrl + H
* 創(chuàng)建快捷鍵方式 : 在對應(yīng)的MenuItem后面以" _"開頭削咆,后面添加快捷鍵標(biāo)志
* 快捷鍵標(biāo)志規(guī)則 :
* % = 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到對應(yīng)Insecptor面板
/*
* 在Inspector中對應(yīng)的組件中右鍵中添加菜單
* MenuItem("CONTEXT/[ComponentName]/[DisplayName]")
* static void FunctionName(MenuCommand command) { //function body code }
*/
[MenuItem("CONTEXT/Camera/Item")]
static public void Item(MenuCommand command)
{
//command.context獲取對應(yīng)Object
Camera camera = command.context as Camera;
Debug.Log(string.Format("light info : name = {0}", camera.name));
}
四鳞陨、創(chuàng)建編輯窗口
前面了解了編輯菜單的制作瞻惋,現(xiàn)在,我們來學(xué)習(xí)下編輯窗口怎么做掏导。
其實(shí)羽峰,一個(gè)編輯窗口就是一個(gè)EditorWindow,翻譯過來也就是編輯窗口啦值纱。
首先履植,創(chuàng)建一個(gè)腳本,繼承EditorWindow凿滤,也就是創(chuàng)建了一個(gè)編輯窗口了庶近,只不過沒有顯示罷了。
<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;
//初始化投队,也就是一個(gè)MenuItem,當(dāng)點(diǎn)擊時(shí)調(diào)用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)); //獲取到窗口息楔,并且顯示
//實(shí)例化并且設(shè)置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渲染圃泡,每幀調(diào)用
void OnGUI()
{
//創(chuàng)建要顯示在編輯窗口的內(nèi)容
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) //點(diǎn)擊事件發(fā)生在當(dāng)前EditorWindow上
{
Vector2 mousePos = currentEvent.mousePosition;
if (contextRect.Contains(mousePos)) //點(diǎn)在矩形范圍內(nèi)
{
menu.ShowAsContext(); //顯示menu
currentEvent.Use();
}
}
}
//回調(diào)
static void Callback(object obj)
{
Debug.Log("Selected: " + obj.ToString());
}
}
這就是創(chuàng)建一個(gè)面板的代碼了颇蜡,可以直接復(fù)制到自己的工程中拯啦,創(chuàng)建如下窗口
對于里面的OnGUI代碼褒链,就是用到UnityEditor相關(guān)類中的一些類了,大家可以研究下甸鸟。
<strong>最后兵迅,文章就到這了,文筆有限刻恭,望大家見諒扯夭。
歡迎各路英雄互相討論學(xué)習(xí)。</strong>