[Unity2018.3新功能]Prefab巢狀和變體
本文節選自洪流學堂公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。
洪流學堂公眾號回覆專欄
,檢視更多專欄文章。
大智:“今天我們要學的內容是Prefab中全新的部分,也就是巢狀的Prefab。”
小新:“為什麼需要巢狀的Prefab呢?”
大智:“我給你舉個例子你就知道了。比如說你有一張桌子,這個桌子在遊戲中會單獨使用,但是也會作為一些Prefab的子物體,比如說房子Prefab的子物體中有桌子。在舊的Prefab系統中,如果你想修改桌子,那必須修改桌子Prefab和所有包含了這個桌子的Prefab。”
小新:“哦,我明白了,如果Prefab可以巢狀,那就相當於把桌子Prefab嵌入房子Prefab,修改桌子Prefab時,房子Prefab裡的桌子也會自動變化,大大減少了維護修改的成本。”
大智:“沒錯哦”
巢狀Prefab
巢狀Prefab,顧名思義就是Prefab中還能有Prefab。嵌入的Prefab自身會連結到一個Prefab資產,同時還能作為一個Prefab的子物體。這在之前(2018.2之前)的Prefab系統中是不可能實現的,因為之前的Prefab是一個整體。
新增巢狀Prefab
要想將一個Prefab的子物體制作成巢狀Prefab,需要在Prefab模式下進行操作。
1、進入Prefab模式。在Prefab模式下,子物體有兩種形態。一種是普通子物體,物體圖示顯示為灰色的立方體。另外一種是巢狀Prefab物體,會顯示為藍色的立方體圖示。
2、此時可以將任意子物體拖拽到Project視窗中形成Prefab資產,這時候該物體的圖示就會變成藍色,同時該物體實質上會變成Prefab資產的一個Prefab例項。也可以對這個巢狀的Prefab例項設定覆寫屬性。
給Prefab例項巢狀Prefab
你也可以給Prefab例項新增一個巢狀的Prefab例項,這種情況不需要在Prefab模式下操作,類似新增一個普通GameObject,只需要將這個Prefab資產拖為Prefab例項的子物體即可。
這種情況下物體圖示的右下角有一個加號,實質是一種新增子物體的覆寫,特殊之處是這個新增的子物體是一個Prefab例項。
和其他覆寫類似,這種覆寫也可以Apply到Prefab資產中。一旦Apply以後,物體右下角就不會再顯示加號小圖示,因為它不再是一個覆寫,而是應用到了Prefab資產中。
Prefab變體(Variant)
如果你想預先定義一些Prefab的變種,那Prefab變體這個新功能就很有用。
比如,你想在遊戲中有很多不同種類的機器人,這些機器人都是基於一個基本的機器人Prefab。但是你想要不同種類機器人有各自不同之處,比如一些機器人手裡拿著不同的物體,一些移動速度不同,一些發出特殊的音效等等。
怎麼做呢?你可以先設定好一個基礎的機器人Prefab,這個Prefab包含了所有機器人共有的行為,然後你可以建立多個不同的Prefab變體:
- 讓機器人移動速度不同:可以使用指令碼來修改機器人的速度
- 讓機器人拿不同的物體:給機器人的手新增不同的物體
- 讓機器人音效不同:給AudioSource元件設定不同的音訊檔案
一個Prefab變體會繼承**基Prefab(base prefab)**的所有屬性,Prefab變體會覆寫基Prefab中的屬性。一個Prefab變體可以基於任何Prefab或Prefab變體。
建立Prefab變體
基於Prefab資產建立Prefab變體有很多方法:
1、你可以在Project視窗中,在Prefab上右鍵,選擇Create > Prefab Variant。這會基於選中的Prefab建立一個變體。你可以開啟Prefab變體,進入Prefab模式,然後編輯新增覆寫。
2、你也可以將Hierarchy中的Prefab例項拖到Project視窗中,這時候會彈出一個對話方塊:建立一個原始(Original)Prefab還是建立基於這個Prefab的變體?如果選擇Prefab Variant,會建立一個Prefab變體,並且這個Prefab變體包含了Prefab例項上所有的覆寫資料。你可以開啟這個Prefab變體,進入Prefab模式,然後編輯新增移除覆寫。
通過Prefab變體建立的Prefab例項在Hierarchy中的圖示有所不同:
編輯Prefab變體
當在Prefab模式下開啟Prefab變體時,根物體會顯示為一個Prefab例項(圖示是藍色的立方體),代表這個Prefab變體基於的Prefab資產。對這個Prefab變體的編輯,實質上在基Prefab上的覆寫。
和Prefab例項類似,在Prefab變體中,你可以使用Prefab覆寫,比如修改屬性值、新增移除元件、新增子物體。但是也有一些限制,和Prefab例項類似:你不能在Prefab變體中修改父子結構(這些結構來自基Prefab);你不能刪除基Prefab中有的子物體(不過你可以通過設定active為false來達到和刪除一樣的結果)。
注意
當你在Prefab模式下編輯Prefab變體時,你需要知道Apply這些覆蓋會將修改應用到基Prefab,基Prefab會發生變化!你通常不想進行這樣的操作。Prefab變體的意義在於提供一個便捷的方法來儲存有意義、可複用的Prefab覆寫,通常應該保持是覆寫,而不是應用到基Prefab中。
當你開啟Prefab例項/變體的Overrides按鈕時,你可以看到頂部明確顯示了這些覆寫基於的Prefab,這些覆寫儲存在哪個例項/變體中。並且在Prefab變體中,Apply All的按鈕也會明確顯示為Apply All to Base來避免潛在的誤操作。
總結
大智:“今天講到的都是Prefab系統的新功能,可以看到這些功能給Prefab系統添加了非常強有力的武器,Prefab也能適用更多的情景。以前可能需要多Prefab的方式,以後會變成Prefab+巢狀Prefab+Prefab變體的方式。”
小新:“跟程式碼中的繼承似的,可以少寫很多程式碼,增加重用。”
大智:“沒錯,思想都是類似的。你能聯想到程式碼中非常好,學科之間其實有很多聯絡,很多思想可以在不同的地方複用。”
今日思考題
大智:“試一下Prefab的巢狀和變體,結合之前做過的專案,看看能給你的專案帶來什麼。”
小新:“好嘞!”
大智:“收穫別忘了分享出來!也別忘了分享給你學Unity的朋友,也許能夠幫到他。”
洪流學堂公眾號回覆專欄
,檢視更多專欄文章。
《鄭洪智的Unity2018課》,傾盡我8年的開發經驗,結合最新的Unity2018,帶你從入門到精通。