配合視頻食用效果更好哦~
Step by step的太空垃圾清理游戲教程-Part 4
作為太空環(huán)境保護(hù)者,除了控制飛船移動(dòng)外,我們還可以切換前視鏡和后視鏡。在前視鏡狀態(tài)下,駕駛員需要駕駛飛船碰撞垃圾來(lái)收集它;在后視鏡的狀態(tài)下,駕駛員只需要點(diǎn)擊垃圾,垃圾就會(huì)自動(dòng)被收集。在本節(jié)中,我們將用trigger,camera,screen和tag來(lái)完成這兩個(gè)狀態(tài)。
切換前后鏡頭 – enabled & SetActive
首先,讓我們實(shí)現(xiàn)切換前后鏡頭的功能。我們已經(jīng)有了一個(gè)主鏡頭“Main Camera”在飛船前側(cè)作為主視角。接下來(lái),需要另一個(gè)鏡頭放到飛船后側(cè)。
-
GameObject - Camera 新建一個(gè)鏡頭。更改名為“Back Camera”
-
將Back Camera移動(dòng)到Spacecraft的下方,成為Spacecraft的子物體(child)
-
開(kāi)始運(yùn)行后,Back Camera也會(huì)跟著Spacecraft一起移動(dòng)了
-
-
將鏡頭的位置移動(dòng)到飛船的后側(cè),調(diào)整角度到合適的視角。
-
單擊鏡頭,在場(chǎng)景右下角能夠看到鏡頭的視角
-
添加后視鏡頭后,我們來(lái)完成前后鏡頭的切換。我選擇的交互方式是添加一個(gè)“前/后”的按鈕,用來(lái)轉(zhuǎn)換前后鏡頭。當(dāng)然,也有其他同樣合適的方式,其中邏輯都是類(lèi)似的。
建一個(gè)按鈕(Button):
-
右擊“Canvas” – UI – Button-TextMeshPro
-
TextMeshPro指的是按鈕上的文字,可以用TextMeshPro而不僅僅是簡(jiǎn)單的Text。如果是第一次用到Button,在彈出的對(duì)話框中選擇“import TMP Essentials”
-
Button的初始結(jié)構(gòu)是Button - Text。在Button的“Image”中調(diào)整按鈕的背景,Text中修改文字和字體...
-
-
重命名為“Back Camera Button”。選擇合適的背景顏色。將按鈕的文字改成“Back Camera”。調(diào)整按鈕的大小和位置。
-
復(fù)制整個(gè)按鈕,用作前鏡頭切換。只需要修改名稱(chēng)和文字為“Front Camera”。
-
兩個(gè)按鈕是為了能夠切換。
-
添加按鈕后,我們可以用它來(lái)控制兩個(gè)鏡頭的“開(kāi)/關(guān)“。這里要用到一個(gè)常用的功能——SetActive。通過(guò)把后面的參數(shù)設(shè)置為T(mén)rue或False,它能夠把某個(gè)GameObject設(shè)置為Active(開(kāi))或inactive(關(guān))。
-
新建一個(gè)Script,命名為“CameraManager”。
-
新建兩個(gè)公開(kāi)的變量frontCam和backCam,用來(lái)代表兩個(gè)鏡頭。
public Camera frontCam;
public Camera backCam;
-
在Start中,用enabled來(lái)設(shè)置兩個(gè)鏡頭的初始狀態(tài)
frontCam.enabled = true;
backCam.enabled = false;
-
新建兩個(gè)公開(kāi)的按鈕變量frontButton和backButton
public Button frontButton;
public Button backButton;
-
記得先在script的頂端導(dǎo)入U(xiǎn)nityEngine.UI,這條指令使我們能夠運(yùn)用Button
using UnityEngine.UI;
-
在Start中,用AddListener設(shè)置兩個(gè)按鈕在被按時(shí)的要執(zhí)行的操作
backButton.onClick.AddListener(BackClick);
frontButton.onClick.AddListener(FrontClick);
-
AddListener是一個(gè)常用的監(jiān)聽(tīng)方法。前面加上onClick,Listener會(huì)在按鈕被按到的時(shí)候執(zhí)行后面參數(shù)中的方法。因此AddListener在設(shè)定按鈕時(shí)很常用。
-
來(lái)定義BackClick和FrontClick兩個(gè)方法。
void BackClick()
{
frontCam.enabled = false;
backCam.enabled = true;
backButton.gameObject.SetActive(false);
frontButton.gameObject.SetActive(true);
}
void FrontClick()
{
backCam.enabled = false;
frontCam.enabled = true;
frontButton.gameObject.SetActive(false);
backButton.gameObject.SetActive(true);
}
-
在被點(diǎn)到后,它們要做的是:控制相應(yīng)鏡頭的開(kāi)關(guān)、關(guān)掉另一個(gè)鏡頭、關(guān)掉此按鈕、打開(kāi)另一個(gè)按鈕
(按鈕邏輯圖)
-
保存并回到編輯器,新建一個(gè)空的GameObject,命名為“Camera Manager”。
-
將CameraSwitch拖拽到Camera Controller中。并將公開(kāi)變量賦值。
獲取和轉(zhuǎn)換屏幕點(diǎn)擊位置 – Touch & Raycast
后視鏡狀態(tài)中,如果玩家點(diǎn)擊太空中的垃圾,垃圾將會(huì)消失(被收集)。Unity用Touch這種類(lèi)型來(lái)代替觸碰屏幕的動(dòng)作。Touch有很多自帶的屬性方便運(yùn)用,比如phase代表觸碰的階段,position代表屏幕上被觸碰的像素點(diǎn)位置等??梢杂肐nput.touchCount> 0這個(gè)條件來(lái)判斷屏幕是否被觸碰,如果觸碰的個(gè)數(shù)touchCount大于0,就說(shuō)明有觸碰存在,就是時(shí)候進(jìn)行下一步了。
前面提到,可以用touch.position獲取被觸碰的像素點(diǎn)位置,就能得到玩家想要點(diǎn)擊的地方。但問(wèn)題是,屏幕是一個(gè)2D的平面,但我們的游戲是3D的世界,將得到的(x,y)直接當(dāng)成(x,y,z)使用顯然行不通。所以,我們需要將2D位置轉(zhuǎn)換成3D鏡頭中的Ray。Ray的本意是“射線”,有著方向和起點(diǎn)。它與touch.position的最大不同在于,前者是相對(duì)于鏡頭,而后者是相對(duì)于屏幕。最后,將射線轉(zhuǎn)換為RaycastHit,指的是射線碰到的物體。注意,只有帶有collider的物體才能夠被射線觸碰到。點(diǎn)開(kāi)兩種垃圾的prefab,它們都應(yīng)該有collider。
(position → Ray → RaycastHit)
-
雙擊打開(kāi)spacecraft代碼文件,
-
在update中,首先判斷是否在后視鏡頭的狀態(tài)下。如果是,進(jìn)行后續(xù)。如果不是,則不需要做任何事。
-
-
創(chuàng)建公開(kāi)的鏡頭變量backCam
-
在update中,判斷backCam是否為enabled的狀態(tài)
if (backCam.enabled) // Only enable touch-collecting when back camera is active
{
}
-
判斷是否有點(diǎn)擊存在。如果發(fā)生了點(diǎn)擊,對(duì)于每個(gè)點(diǎn)擊我們都需要執(zhí)行相同的步驟:
if (Input.touchCount> 0)
{
foreach (Touch touch in Input.touches)
{
...
}
}
-
先獲取touch的位置,用ScreenPointToRay轉(zhuǎn)換為Ray。再將ray轉(zhuǎn)換為RaycastHit。通過(guò)RaycastHit的屬性得到點(diǎn)擊到的gameObject
Ray ray = backCam.ScreenPointToRay(touch.position); // Convert ray to camera view pos
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
...
}
-
最后,我們用hit.transform.gameObject來(lái)獲取點(diǎn)擊到的物體,并使之消失
GameObject obj_hit = hit.transform.gameObject;
obj_hit.SetActive(false);
-
保存代碼,回到編輯器。別忘了拖拽給backCam賦值
分類(lèi)好幫手 – Tag
現(xiàn)在,在后視鏡中,被點(diǎn)擊到的物體都會(huì)消失。但問(wèn)題是,垃圾之外的物體,比如星球、人造衛(wèi)星等任何有collider的物體,都會(huì)消失。因此,需要一個(gè)條件來(lái)判斷碰到的物體是不是垃圾。Unity中,常用的分類(lèi)物體方法是加“標(biāo)簽”tag。可以自己創(chuàng)造標(biāo)簽,比如Moon Trash,Space Trash。多個(gè)物體可以用同一個(gè)標(biāo)簽。Unity還貼心的準(zhǔn)備了很多好用的方法,比如FindWithTag,CompareTag等,非常方便。
給場(chǎng)景中的垃圾加上標(biāo)簽。
-
在Inspector中,選擇tag的下拉鍵,點(diǎn)擊“Add tag…“
(給物體加上標(biāo)簽)
(創(chuàng)建新標(biāo)簽)
-
在新窗口中點(diǎn)擊加號(hào),輸入標(biāo)簽的名稱(chēng)。分別創(chuàng)建”Moon Trash“和”Space Trash“兩個(gè)標(biāo)簽。
-
點(diǎn)擊每一個(gè)垃圾物體,下拉tag,剛剛創(chuàng)建的標(biāo)簽中選擇相應(yīng)的。
加上標(biāo)簽后,還需要在script中加入判斷標(biāo)簽的條件。
-
雙擊打開(kāi)spacecraft代碼文件,在obj_hit.SetActive(false);之前加上判斷條件
if (obj_hit.CompareTag("Moon Trash"))
{
obj_hit.SetActive(false);
}
if (obj_hit.CompareTag("Space Trash"))
{
obj_hit.SetActive(false);
}
-
保存
注意,CompareTag后的標(biāo)簽內(nèi)容一定要和創(chuàng)建的 一 模 一 樣!不然的話,CompareTag會(huì)返回false值,也就無(wú)法進(jìn)行后面的步驟了。
在Unity中運(yùn)行時(shí),你可能會(huì)發(fā)現(xiàn)點(diǎn)擊垃圾沒(méi)有反應(yīng)。這不是你的錯(cuò),只是鼠標(biāo)的點(diǎn)擊無(wú)法被算作“Touch”。也就是說(shuō),只有在手機(jī)上測(cè)試才會(huì)有效果。后面的章節(jié)會(huì)介紹在手機(jī)上測(cè)試的簡(jiǎn)便方法。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-822699.html
如果有任何疑問(wèn)或者建議,也歡迎在下方留言評(píng)論喲~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-822699.html
到了這里,關(guān)于「Unity入門(mén)」Step by step的太空清理垃圾游戲Part 4: 觸碰收集垃圾的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!