【Unity3D實(shí)用技巧·一】自定義快捷鍵
如果說一定要選出世界上最喜歡用快捷鍵的群體的話,那么一定是程序員了。
——龍兒
????一方面為了激勵自己保持學(xué)習(xí),并將學(xué)習(xí)當(dāng)中碰到的一些問題記錄下來,另一方面也是感嘆Unity中文互聯(lián)網(wǎng)資料還是不夠齊全繁多,有時候一個簡單的問題要查詢許久,并且查到的也經(jīng)常是東一榔頭西一棒子、不夠系統(tǒng)化,有些資料甚至語焉不詳,因此自然模仿無數(shù)前輩萌生了自己寫B(tài)log的想法,這便是《Unity3D實(shí)用技巧》。
????本欄目中我計(jì)劃結(jié)合自身的實(shí)際工作、學(xué)習(xí)經(jīng)歷不斷分享一些不復(fù)雜卻實(shí)用的,能有效提高U3D工程效率的技巧。
????正如我一開始所說的,似乎習(xí)慣用鍵盤工作的人總是恨不得全面拋棄鼠標(biāo),最好工作時手完全不要離開鍵盤,其中程序員一定是佼佼者,畢竟思路到一半被煩人的移動鼠標(biāo)打斷總是痛苦的。而使用U3D過程中,自然而然的針對一些常用的需求,比如坐標(biāo)歸零、層級排序、切換正交視圖等,Unity居然沒有準(zhǔn)備快捷鍵,真讓人惱火,于是第一期就是分享如何定義自己的快捷鍵。
????實(shí)際上自定義快捷鍵的本質(zhì)是通過快捷鍵調(diào)用Unity編輯器菜單中的一個菜單項(xiàng),而編輯器的菜單項(xiàng)是高度可自定義的,也就是說,我們可以編寫一些自己的功能,自己的邏輯,并隨時調(diào)用它。
????簡單的介紹過后,我們先直接以一個實(shí)例開始!

快捷鍵與"Hello!World!"
????我們在Unity工程中創(chuàng)建好上面的腳本,此時在編輯器中按下Alt+Q就可以看到我們的控制臺中已經(jīng)打印出了"Hello!World!"字樣。

????截止于此,我們就可以快速的打印"Hello!World"了。
????剛接觸Unity的人可以先按照上面的步驟簡單實(shí)踐一下,加深理解。

進(jìn)階!實(shí)踐!與[MenuItem()]標(biāo)簽
????下面先直接貼一段用于將單個選中物體transfrom重置的代碼,然后結(jié)合代碼我們進(jìn)一步深入了解MeunItem是什么?能干什么?為什么?
????這樣我們就簡單的實(shí)現(xiàn)了通過快捷鍵“Alt+r”使選中的物體transform置零的操作。他在表現(xiàn)上和我們手動在transform組件上點(diǎn)擊Reset是一致的。
????相似的我們實(shí)際上可以在方法體中寫任何的自定義內(nèi)容。
????但是有一點(diǎn)需要注意,我們自定義的快捷鍵不能和Unity已經(jīng)有的快捷鍵沖突,那么如何查看unity內(nèi)置的快捷鍵呢?

我們可以在Edit的Shortcuts中打開unity的快捷鍵窗口,同時也可以在這里設(shè)置內(nèi)置的快捷鍵命令。
????另外這里是一些常用的自定義快捷鍵:
????ctrl %
????shift #
????alt &
????單個字母快捷鍵前綴 _
????如果只是想了解如何在Unity中自定義快捷鍵那么到這里其實(shí)已經(jīng)介紹完80%的內(nèi)容了,剩下的細(xì)枝末節(jié)大家可以在網(wǎng)上檢索Unity編輯器擴(kuò)展自行查閱更多的相關(guān)內(nèi)容。
????我們重點(diǎn)來關(guān)注一下背后的原理,為什么這樣做就可以實(shí)現(xiàn)自定義快捷鍵了呢?從原理層面,我們到底做了什么?
????底層一點(diǎn)的層面講,Unity是通過“反射”來遍歷、檢索、調(diào)用對應(yīng)的函數(shù)來實(shí)現(xiàn)功能的,具體的機(jī)制我們可以搜索“Unity 反射”相關(guān)的字樣進(jìn)一步了解,我們的[MenuItem()]標(biāo)簽原理也是類似的,通過給自定義靜態(tài)方法加標(biāo)簽,我們讓編輯器自動生成了一個菜單項(xiàng),并在觸發(fā)這個菜單項(xiàng)時,回調(diào)對應(yīng)的方法。

?PS:針對Unity反射機(jī)制與標(biāo)簽的原理的解析,這里推薦一下CSDN上,漫漫無期老師和用c#寫unity的杰寶老師以及宿春磊Charles老師的文章,我們可以從中管中窺豹得以照見Unity的運(yùn)行機(jī)理。

? ? 因?yàn)椴皇谴颂幱懻摰闹攸c(diǎn),所以不再過多深入解析,而是我們直接來看我們實(shí)用的特性標(biāo)簽[MenuItem()]
????面對不了解的API,我們首先查詢一下手冊,查詢Unity官方手冊可以看到如下的解釋

????直接看重點(diǎn),用于向主菜單和上下文檢視菜單創(chuàng)建菜單項(xiàng),僅可對靜態(tài)函數(shù)使用,與我們上文的實(shí)踐相符。這說明了該標(biāo)簽的作用確實(shí)是創(chuàng)建菜單項(xiàng),我們回頭看看上面實(shí)例在工程中的體現(xiàn)。

????確實(shí)創(chuàng)建了兩個菜單項(xiàng),接下來我們刪除掉實(shí)例中的快捷鍵,并手動點(diǎn)擊它試試。

????實(shí)踐證明通過快捷鍵或者手動點(diǎn)擊得到的結(jié)果完全一致。
????此時可能有些寫過編輯器腳本的朋友也想起了,我們創(chuàng)建自定義窗口時,也是通過類似的方法創(chuàng)建的,我們也可以在此試驗(yàn)一下。
????點(diǎn)擊創(chuàng)建出來的菜單項(xiàng)后,得到了這樣的結(jié)果。

????結(jié)果很好的符合了我們的預(yù)期,這個例子意味著我們可以通過類似的方式來DIY自己的U3DEditor。
????繼續(xù)回頭看MenuItem標(biāo)簽,我們發(fā)現(xiàn)標(biāo)簽其實(shí)是有三個重載的,除了除了菜單項(xiàng)的路徑,我們還可以顯式的指定他是否是驗(yàn)證函數(shù),指定他的優(yōu)先級。

????官方手冊一貫的不說人話,我們直接上實(shí)例來說明第二個參數(shù)的用途。

????????發(fā)現(xiàn)只創(chuàng)建了名為TestFalse的菜單項(xiàng),這是怎么回事呢?我們直接查看一下MenuITem的源碼。
????翻譯一下:
????// ? isValidateFunction:?
????// ? ? 如果 isValidateFunction 為 true,這是一個驗(yàn)證函數(shù),在與相同 itemName 的菜單函數(shù)被調(diào)用之前執(zhí)行。
????似乎暗示了我們需要一個相同名稱的菜單項(xiàng),那么我們接著實(shí)踐一下。

????此時創(chuàng)建了菜單項(xiàng),但他無法點(diǎn)擊,永遠(yuǎn)是Disabled狀態(tài),我們回頭繼續(xù)查閱一下Unity的手冊。
????也就是說,[MenuItem()]特性要求我們的驗(yàn)證函數(shù)返回一個Bool值,如果這個值是true則啟用我們的菜單項(xiàng),反之不啟用,我們實(shí)踐一下。


????至于最后一個優(yōu)先級,我們直接看一個例子就能了解清楚。

????說明了兩件事:1、優(yōu)先級越小越靠上 2、當(dāng)優(yōu)先級間隔大于10時,會分組
????到此,我們隊(duì)[MenuItem()]的了解和應(yīng)用也說得七七八八了,只剩下一些小問題寫在最后。

番外1:驗(yàn)證函數(shù)的調(diào)用問題
?? ?上面雖然說了驗(yàn)證函數(shù),但是較真的人肯定會好奇,我們究竟是什么時候調(diào)用驗(yàn)證函數(shù)的呢?不妨測試一下。
? ? 這樣一來,我們只需要觀察Unity在什么時候會打印消息就可以知道了。

????只是創(chuàng)建新物體,當(dāng)數(shù)量為5的時候,并未調(diào)用驗(yàn)證函數(shù)。

????依然沒調(diào)用。

????數(shù)量到了7,此時毫無疑問驗(yàn)證函數(shù)的結(jié)果從false變?yōu)榱藅rue,但是他依然沒有調(diào)用。
????我們嘗試看一下菜單項(xiàng)。

我們發(fā)現(xiàn),當(dāng)我們“試圖調(diào)用被驗(yàn)證函數(shù)時”,驗(yàn)證函數(shù)被調(diào)用了,無論我們是否實(shí)際調(diào)用了被驗(yàn)證函數(shù)。有些類似對象的構(gòu)造方法,當(dāng)我們實(shí)例化類時,調(diào)用了類的構(gòu)造方法,無論我們是否實(shí)際使用了這個類的對象。

番外2:物體右鍵菜單與Assets窗口的右鍵菜單
????1、只需要將路徑設(shè)為“GameObject/實(shí)際菜單項(xiàng)名稱”,并且優(yōu)先級小于等于49就可以添加右鍵菜單了
????2、只需要將路徑設(shè)為“Assets/自定義菜單_Assets”,就可以添加Assets的右鍵菜單了,下面是示例



結(jié)語:
????寫的有些啰嗦,但是需要了解的和一些拓展應(yīng)用應(yīng)該都介紹到位了,希望能有機(jī)會幫到一些人;完整的代碼因?yàn)閼芯筒环帕?,?shí)際起作用的代碼都在文中了,有需要的自行取用即可。
????轉(zhuǎn)載自便,標(biāo)不標(biāo)出處都可以。