天天看點

《Unity 5.x遊戲開發實戰》一2.4 金币采集

本節書摘來異步社群《unity 5.x遊戲開發實戰》一書中的第2章,第2.4節,作者: alan thorn 譯者: 李華峰 責編: 胡俊英,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。###2.4 金币采集

前面已經設計了一個金币計數變量,通過這個變量就可以随時地獲知目前場景中金币的數量。不過,現在遊戲仍然沒有實作金币采集功能。下面就來完善這個功能。當玩家接觸到金币後,也就是說,當玩家穿過金币或者碰撞到金币的時候,就可以看作這個金币被成功采集了。

如果想要确定玩家是否與金币發生接觸,就需估算出玩家和金币的體積,這樣才能檢測出兩個物體在空間中是否出現重疊。這是unity通過碰撞體(collider)來實作的。碰撞體(collider)是一種附加在網格上的特殊實體對象,當兩個遊戲對象在空間上有重疊時,碰撞體就會檢測到。fpscontroller對象(第一人稱視角控制器)上已經自帶了碰撞體對象,它使得控制器更像是一個人的身體。在場景中選中fpscontroller對象(第一人稱視角控制器),然後就可以看到圍繞在主攝像頭周圍的綠色線框,它是膠囊形狀的。如圖2.15所示,“character controller”具有一個和玩家身體形狀相仿的碰撞體。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

fpscontroller 中包含了一個“character controller”元件,這個元件包含“radius”“height”和“center”等選項,規定了場景中角色的實體屬性。如圖2.16所示,fpscontroller 中已經包含一個“character controller”,在此遊戲中,這些選項的值都不需要修改,保留預設值即可。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

金币遊戲對象中隻包含了一個膠囊碰撞體(capsule collider)元件,這是當初在建立圓柱體對象時系統自動添加上的,它與場景中的金币的大小差不多,在它的“character controller”元件中沒有添加任何的屬性和動作,這是很正常的,因為與fpscontroller這種會動的運動物體不同,金币是一個不會動的靜态物體。如圖2.17所示,包含了膠囊碰撞體(capsule collider)元件的圓柱體對象(cylinder)。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

對于現在這個遊戲,仍然為金币遊戲對象選擇使用膠囊碰撞體(capsule collider)元件,如果希望改用一個不同的碰撞體,比如一個盒子或者球形,來代替這個預設元件,就需要首先将金币上任何已有的碰撞體元件移除。具體操作為:單擊位于遊戲檢查(inspector)面闆中元件右上角的齒輪圖示,然後從上下文菜單中選中“remove component”,如圖2.18所示。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

接下來,選中一個遊戲對象,然後通過應用程式菜單依次選中“component | physics”,然後在彈出的菜單中選中一個合适形狀,如圖2.19所示。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

不論使用哪種類型的碰撞器,這裡都還有一點小問題。那就是當在進行遊戲的時候,如果想要穿過金币,就會發現無法成功,反而會被金币擋在那裡。這是因為現在的金币是一個固态的實體對象,是以fpscontroller對象是無法穿金币而過的。但是本遊戲可不是這麼設計的,金币不應該是一個遊戲中的“攔路石”,而是一種可以被采集的對象,這就是說當玩家從金币中穿過時,就可以采集到金币,同時金币也會在場景中消失。操作方法為:選中金币對象,然後在它的遊戲對象檢查(inspector)面闆中的膠囊碰撞體(capsule collider)元件中選中“is trigger”複選框。這個“is trigger”選項适用于所有的碰撞體類型,主要用來檢測與其他碰撞體是否發生碰撞,并且在發生碰撞時允許它們通過,如圖2.20所示。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

此時,在玩遊戲時,fpscontroller就可以輕松地穿過場景中的所有金币。然而,玩家接觸到金币之後,金币并不會消失,同樣也不會被玩家采集到。要完善這些功能,需要向“coin.cs”檔案中添加更多的代碼。首先添加一個ontriggerenter()函數,當遊戲對象,例如遊戲玩家,進入了一個碰撞體時,就會自動地調用。現在,添加一句debug.log語句,當玩家進入到一個碰撞體時,就會輸出一條調試消息,這隻是為了進行測試,代碼示例2.4如下所示。

注意 

首先單擊工具欄上的“play”按鍵來測試樣例2.4中的代碼。當穿過一個金币時,就會觸發這個函數并展示一個資訊。不過,這裡還是存在一個問題,到底是什麼觸發了這個函數呢?很明顯一定有什麼東西穿過了金币,但是到底是什麼呢?是玩家,敵人又或者是一個掉落的磚頭,還是其他的什麼東西?為了區分開這些内容,需要使用“tag”。“tag”可以為場景中的指定物體打上特殊的标記或者标簽,這樣就可以在代碼中輕松将玩家和其他對象區分開。要知道在本遊戲設計中,隻有玩家才可以收集金币。是以,需要為玩家對象添加一個名為“player”的“tag”。要做到這一點,需要首先在場景中選中這個對象,然後在對象檢查(inspector)面闆中選中tag下拉清單框,在tag的下拉清單中選中“player”。這樣就将fpscontroller标記為“player”對象,如圖2.21所示。

《Unity 5.x遊戲開發實戰》一2.4 金币采集

fpscontroller已經被标記為了player。接下來就按照代碼示例2.5所示重新定義coin.cs類。現在這個類已經可以完成金币的采集工作,當玩家接觸到金币後,金币就會消失,同時将金币的數量減1。

下面對代碼示例2.5進行如下總結。

每當fpscontroller接觸到了金币碰撞體的時候,unity就會自動地調用一次ontriggerenter()函數。

當調用ontriggerenter()函數時,參數col中存儲在這次接觸中進入碰撞體的物體資訊。

函數comparetag()的作用是用來判斷到底與這個碰撞體發生碰撞的是不是player。

使用destroy函數來銷毀一個金币對象。當這個函數被調用時,還會觸發ondestroy()函數,這個事件會使得金币總數減1。

至此,已經建立好了第一個可以工作的金币了。現在遊戲中的玩家就可以走近并采集這個金币,然後這個金币就會被從場景中移除。不過,這個場景中不應該隻包含一個金币,而是很多個金币。可以通過對這個已經做好的金币進行複制來解決這個問題,當然要将複制好的金币放置到其他不同的地方。其實還有更好的解決辦法,接下來将進行介紹。