分類:Unity、C#、VS2015 創建日期:2016-04-02 一、簡介 預製體(Prefab,也叫預設)是“存儲在工程視圖(Project View)中”的一種特殊的資源,是一種可重覆使用的游戲對象(GameObject)的容器。 如果在Project中有多個預製體(Prefab),為了容易... ...
分類:Unity、C#、VS2015
創建日期:2016-04-02
一、簡介
預製體(Prefab,也叫預設)是“存儲在工程視圖(Project View)中”的一種特殊的資源,是一種可重覆使用的游戲對象(GameObject)的容器。
如果在Project中有多個預製體(Prefab),為了容易查找,可將這些預製體全部保存到Project視圖中Assets文件夾的Prefabs子文件夾下。
Prefabs子文件夾下的的所有預製體都可以放入到多個場景中,而且即使在同一個場景中仍然可以多次使用。
向場景中添加一個預製體就是創建該預製體的一個實例。另外,由於場景(Scene)中所有預製體的實例都會自動鏈接到Project中的原始預製體(Prefab),因此這些實例本質上就是原始預製體的克隆。或者說,不論場景中有多少個預製體實例,只要僅僅對Project中某個Prefab作出任何更改,你就會看到這些更改馬上就能應用於場景中該Prefab的所有實例。
1、在工程視圖(Project)中創建預製體(Prefab)
要在Project中創建一個預製體(Prefab),只需將你在場景(Scene)中創建的一個游戲對象 (GameObject)拖放到工程視圖(Project View)中的某個Prefab中。
如果層級視圖(Hierarchy)中的游戲對象(GameObject)的名稱變成藍色,表示Hierarchy中的該對象是一個已經製作好的預製體的實例。此時,你可以根據需要,決定是保留層級視圖 (Hierarchy)中的這個實例還是刪除這個實例,不論你是否保留,都不會影響Project中製作好的原始預製體。
2、在層次視圖(Hierarchy)中創建預製體的實例
要在“當前場景中”創建一個“預製體的實例”,直接從工程視圖(Project View)中將某個預製體拖放到場景(Scene)或層級視圖(Hierarchy)中。
Hierarchy視圖中的“藍色”字體表示該對象是某個預製體的實例。
一旦你創建了預製體的實例,該實例就會自動鏈接到Project中的源預製體,併在層級視圖(Hierarchy)中以“藍色”文字顯示。
在這個截圖中,有3個游戲對象是藍色,表示這都是預製體的實例。
3、在檢視器(Inspector)中操作預製體
(1)粗體的含義
有時候你可能希望僅更改單個預製體實例的屬性,同時還能保持與源預製體的鏈接完整,此時可看到該實例對應的變數名稱變成了粗體,表示這個變數已被重寫。註意,所有重寫的屬性都不會受到源預製體更改的影響。
(2)Select
如果你選擇了某個預製體實例,並希望將所做的更改影響到所有實例,此時可直接在檢視器(Inspector)中單擊【Select】按鈕來選擇更改的原始預製體。
(3)Apply
如果希望用重寫的值更新源預製體及其所有實例,可單擊檢視器(Inspector)中的【Apply】 按鈕。註意,這種“應用”不會對“根位置”和“旋轉”起作用,因為這會影響實例的絕對位置並導致所有實例放在同一個位置。但是,Apply會對根的任何子元素或祖先元素的位置和旋轉起作用,因為它們是相對於根的變換來計算的。
(4)Revert
如果想放棄對特定實例的所有重寫,可單擊【(Revert)】按鈕。
4、導入預製體
將網格資源放入Assets文件夾下時,Unity會自動導入文件,並生成一些類似於網格之外的看起來像預製體的東西。但是,這實際上不是預製體(Prefab),它只是資源文件本身使用的東西。
註意,資源(asset)圖標與預設 (Prefab) 圖標略有不同。
資源是作為一個游戲對象(GameObject)存在於場景中的實例,它鏈接到源資源而不是鏈接到預製體(Prefab)。你可以向該游戲對象(GameObject) 正常添加、刪除組件,。但是你無法對資源本身作任何更改,因為這樣會向資源文件本身添加數據!如果你希望創建一些可重覆使用的東西,那你就應當把它製作成一個預製體。
選擇一個資源實例時,檢視器 (Inspector) 中的【Apply】按鈕將被替換成【Edit】按鈕。單擊此按鈕將為資源啟動編輯應用程式(如 Maya 或 Max)。
二、Prefabs基本用法示例
經過上面的介紹,你應當已經從基本層面上瞭解了Prefabs的概念:Prefabs本質上是GameObjects(預定義的游戲對象)和Components(組件)組成的集合體,是可在游戲中重覆使用的容器對象。
使用Prefabs可以方便地在運行時實例化複雜的GameObjects(游戲對象)。
1、創建游戲對象的方式
在Unity中,有兩種創建對象(Game Object)的方式:
(1)方式1:全部用C#代碼實現。這種方式使用C#代碼從頭開始創建並初始化游戲對象(GameObjects)。
(2)方式2:利用Prefabs實現。即:先製作預製體,運行時再通過代碼實例化預製體。
與方式1相比,方式2(用Prefabs實現)有多個優勢:
l 可以使用一行代碼實例化Prefab,並具有完整功能。而使用代碼創建等效游戲對象 (GameObjects),平均需要五行代碼,還有可能需要更多。
l 可在場景 (Scene) 和檢視器 (Inspector) 中快速設置、測試和修改預製體。
l 可以更改已實例化的預製體,而無需更改實例化預製體的代碼。例如,可將一個簡單的火箭更改成超級火箭,但無需更改代碼。
2、示例—創建一堵牆
為了說明Prefabs的強大,讓我們來看看可用得上Prefabs的一些基本情況:
(1)在不同位置,多次使用單塊“磚”預製體來創建一堵牆。
(2)發射時,火箭發射器實例化一個飛行的火箭預製體。該預製體是一個包含一個網格(Mesh)、剛體 (Rigidbody)、碰撞器 (Collider) 和帶有自己的拖尾粒子系統 (Particle System) 的子游戲對象 (GameObject)。
(3)機器人爆炸成許多碎片。此時完整的操作機器人已毀壞,替換成一個殘破的機器人預製體。該預製體包含分成多個部分的機器人,所有部分均設有自己的剛體 (Rigidbodies) 和粒子系統 (Particle Systems)。有了預製體,你僅用一行代碼就可以將一個對象替換成指定的預製體,從而讓機器人炸成許多碎片。
該示例僅僅是為了說明“使用Prefab創建對象”與“使用代碼創建對象”相比,前者(使用Prefab創建對象)的優勢。
(1)實現方式1
首先演示“使用代碼創建對象”的實現方式,因為只有比較,你才能理解這種方式有什麼缺點。
先在ch03Demos工程的Project視圖的Assets下創建一個名為Scripts的子文件夾,然後在該子文件夾添加一個名為Demo1的C#腳本:
雙擊Demo1腳本,Unity就會自動啟動VS2015並自動在VS2015中打開Demo1.cs文件,而且解決方案資源管理器中Assets下的文件夾結構和Unity中的文件夾結構相同:
將Demo1.cs文件改為下麵的內容:
using UnityEngine; using System.Collections; public class Demo1 : MonoBehaviour { void Start () { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent<Rigidbody>(); cube.transform.position = new Vector3(x, y, 0); } } } }
保存該文件。
切換到Unity,選擇主菜單的【GameObject】->【Create Empty】創建一個空游戲對象,再將Scripts文件夾下的Demo1腳本拖放到剛添加的空游戲對象中。
切換到Game視圖,單擊【播放】按鈕觀察執行效果。此時將看到完全用代碼創建的立方體牆(由於預設使用了重力,牆會自動倒塌):
當然,由於沒有添加紋理,所以此時看到的僅僅是一堵白色的牆(倒塌後還是一個一個的立方體)。若想執行附加操作,例如更改磚塊紋理、摩擦力或剛體的質量,還需要再添加其他的代碼,可見用這種方式實現起來有多麼麻煩。
刪除層次視圖中剛創建的空游戲對象。
(2)實現方式2
第2種中實現方式是先創建一個“牆”預製體,然後再用“創建預製體實例”的辦法來創建多堵牆。
步驟如下:
選擇主菜單的【GameObject】->【3D Object】->【Cube】創建一個立方體:
此時,剛創建的Cube在層次視圖中處於選中狀態。
將Texture文件夾下的brick_D拖放到層次視圖中的這個立方體上。
在Project視圖的Assets文件夾下,添加一個Prefabs子文件夾:
滑鼠右擊Prefabs子文件夾,選擇【Create】->【Prefab】:
將新添加的Prefab的名稱更改為“Brick”。
將在層級視圖中創建的立方體拖放到Project視圖中剛創建的“Brick”上。
這樣就創建好了一個名為“Brick”的預製體(或預設)。
創建預設 (Prefab) 後,在層次視圖中添加的立方體(Cube)已經用不到了,可以從層級視圖 (Hierarchy) 選中它,然後按Delete鍵刪除。
重新添加一個空游戲對象 (GameObject)。
在VS2015解決方案資源管理器項目中的Scripts子文件夾下,添加一個文件名為Demo2.cs的C#腳本(Demo2.cs),然後將其改為下麵的內容:
using UnityEngine; using System.Collections; public class Demo2 : MonoBehaviour { public Transform Brick; void Start () { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { Instantiate(Brick, new Vector3(x, y, 0), Quaternion.identity); } } } }
按<F5>鍵將其附加到Unity,然後按<Shift>+<F5>鍵結束。
切換到Unity,將工程視圖下的該腳本拖放到剛纔添加的Cube上,這就為該對象添加了一個Demo2組件:
另外,此時檢視器 (Inspector) 中將出現一個名為“Brick”的新變數,這個Transform類型的變數可以接受任何游戲對象 (GameObject) 或預製體。
從工程視圖 (Project View) 中,將預製體“Brick”拖放到檢視器 (Inspector)視圖中的Brick變數的值上(作用是:創建預製體的實例作為Brick變數的值):
按下“播放 (Play)”,就會看到同時使用預製體和C#腳本創建的牆:
可見,這種方式實現的腳本代碼不僅非常乾凈,而且可重覆使用這個Brick預製體。
剛開始學習時,你可能想知道為什麼要這樣做,用第1種方式創建立方體不是更靈活和方便嗎?為什麼還要再搞一個Prefab呢?
這是因為使用Prefab,您可以在數秒之內就能完成對它的調整:
- 想要添加或更改所有實例的質量?只需在預製體中添加一個剛體,並一次性調整剛體 (Rigidbody)的重力即可。
- 想為所有實例使用不同的材質 (Material)?只需將材質 (Material) 拖放到預製體上一次。
- 想要更改摩擦力?在預製體碰撞器中使用不同的物理材質 (Physic Material)就行了。
- 想為所有立方體添加一個粒子系統 (Particle System)?向預製體中添加一次子對象即可。
當然,如果僅僅是為了學習操作步驟,找不到brick_D.jpg文件時,隨便找一副其他的.jpg圖片代替也行,反正目標就是給這堵用立方體構造的牆貼滿圖,理解其含義就行了。