在上一節,我們把我們在這次的練習中所需要的所有物件都建立好了。這次就來說明一下如何將程式碼套用在物件上。也會稍微說明一下套用上去的程式碼究竟有甚麼樣個功能。
1.2D卷軸遊戲 #如果你的畫面最後與我上一節相同,那麼這一點其實已經做到了。 3.我希望能有一塊地板可以撐住我的主角。
1.2D卷軸遊戲 2.我想要有一個不知道長甚麼樣子的主角能夠被我的方向鍵控制。他可以: a.左右行走 b.跳 3.我希望能有一塊地板可以撐住我的主角。 4.鏡頭可以跟著主角移動。
※教學內容若有錯誤,歡迎在下方留言向我反應,感謝你們~
※有些程式碼的說明可能不完全,那可能是我目前還不知道XDD
========================================================================
在繼續製作以前,我們先稍微檢查一下之前列出來的架構需求:
2.我想要有一個不知道長甚麼樣子的主角能夠被我的方向鍵控制。他可以:
a.左右行走
b.跳
4.鏡頭可以跟著主角移動。
現在,我們只剩下角色操作的部分,以及要讓鏡頭跟著主角移動。
開始之前,稍微透漏一下,讓鏡頭跟著主角移動,其實只需要一個很簡單的動作。期待一下吧XD
好的!那麼,繼續製作。
-----------------------------------------------------------------------------------------------------------------------------
由於需要透過「程式」讓玩家可以被程式控制,所以,我們需要在Project中新增「C#腳本(C# Script)」
在Project中點擊右鍵→Create→C# Script
建立C#腳本之後,就可以為他取一個你自己看得懂的名字,在這裡我將它命名為「MainCS.cs」
現在,在Assets資料夾中,會有一個C# Script的檔案。
※如果在製作過程中,發現自己不小心按到了甚麼,結果MainCS.cs不見了,有可能是因為你按到了左邊上面那一塊「我的最愛」的清單:
把它點回Assets就有了。
如果點回Assets之後,發現還是沒有MainCS.cs,那就表示你沒仔細看我教學......還沒新增腳本。
※如果你的Assets資料夾裡面的檔案圖示非常小,小到變成了清單:
那你可以調整右下角的卷軸,那可以幫你調整檔案圖示的大小。
建立完成之後,把「MainCS.cs」雙擊點開。
※Unity的IDE有兩種,如果在安裝Unity時沒有特別設定的話,可能會同時有「Visual Studio」與「MonoDevoloped」兩種。看自己習慣用哪一個就用哪一個,我習慣用Mono。
如果需要更改每次開啟腳本的預設程式,可以到Edit→Preferences...
會跳出這個視窗:
然後可以到External Tools→External Scripts Editor選擇自己的預設程式。
打開腳本之後,廢話不多說,直接上程式碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MainCS : MonoBehaviour { //-----a. Transform trans; //-----b. Rigidbody2D rigid; //-----c. // Use this for initialization void Start () { //-----d. trans = GetComponent<Transform>(); //-----e. rigid = GetComponent<Rigidbody2D>(); //-----f. } // Update is called once per frame void Update () { //-----g. if (Input.GetKey(KeyCode.LeftArrow)) { //-----h. trans.Translate(Vector2.left * Time.deltaTime); //-----i. }else if (Input.GetKey(KeyCode.RightArrow)) { //-----j. trans.Translate(Vector2.right * Time.deltaTime); //-----k. } if (Input.GetKeyDown(KeyCode.UpArrow)) { //-----l. rigid.AddForce(Vector2.up * 200); //-----m. } } } |
在開始說明程式碼以前,我們先把腳本套用到我們所需要的物件──「Player」上。
套用腳本的方法有兩種,
第一種:直接在Assets裡的MainCS.cs檔案拖曳到Player物件上。
第二種:點選Player物件,在Inspector中新增元件,元件名稱就是腳本的檔名:
套用上去之後,會看到Player物件最下方出現了腳本的元件,像這樣:
如果看到這個,就表示已經成功套用了。很簡單吧XD
若是迫不及待想要開始操縱角色的話,可以按下試玩鈕。
『方向鍵左右鍵操控方向,上為跳。』
讓一個物件動起來的感覺,是不是頗有成就感啊?
-----------------------------------------------------------------------------------------------------------------------------
再來,我要開始說明上面那段程式碼了。
最上面那三行using是建立腳本之後他自己就會先做好的。如果程式碼中會用到它其他的東西,就會需要自己增加using的內容,不然程式碼可能會無法運作。
比如說如果之後需要在遊戲裡面增加UI介面,並且用程式碼去控制UI介面的功能的話,那到時候就會需要在上面增加一行:
using UnityEngine.UI;
不過,這次的練習中不需要再另外using,所以這部份就跳過,直接用他已經預設好的內容就可以了。
再來我會找一些比較重要的程式稍微說明一下:
a.public class MainCS : MonoBehaviour 這行也是已經預設好的寫法,基本上不用改,但是要特別注意的一點是: 這裡的「MainCS」就是這個腳本的檔名,必須完全相同,否則會錯誤。 |
b.Transform trans; 我們待會要用程式來控制角色移動,所以會需要「改變他的位置」,既然要改變他的位置,那一定會與控制物件位置的元件「Transform」有關。 所以,這行程式就是宣告一個Transform資料型態的變數,並且將它命名為「trans」 |
c.Rigidbody2D rigid; 我們的目的除了讓角色可以移動之外,還要讓角色可以「跳躍」。「跳躍」這個動作是讓角色能夠「抵抗重力」而向上的力道。 讓玩家能夠「抵抗重力」,會與Rigidbody 2D元件有關,所以,這行程式就是宣告一個Rigidbody 2D資料型態的變數,並且將它命名為「rigid」 |
d.void Start () 這行是預設好的程式碼,在「Start ()」方法裡的程式,會在遊戲最一開始被執行一次。 所以這裡放的東西,通常都是變數的預設值、初始運算......等初始的資料。 |
e.trans = GetComponent<Transform>(); 剛剛已經宣告過trans是一個Transform型別的變數。但是,如果只是宣告變數,那個變數並不存在任何意義,所以我們要在遊戲一開始的時候,告訴電腦: 「這個trans變數,就是這個物件的Transform元件」我們以後要用trans這個名字來控制這個物件的Transform元件。 GetComponent,取得元件。 這個函數是用來取得元件用的,至於取得甚麼元件?就是寫在後面的<>中。 ※注意:<Transform>()的()並不是多打的,是他必須這麼書寫,這個在Unity API中的範例有寫使用方法。 有不知道的語法都可以上Unity API尋找,大多都能找得到解答,很好用的。 在我撰寫的程式中,我很直接地將trans變數指向GetComponent<Transform>(),或許有一些人會有疑問:他怎麼會知道我要的是這個物件的Transform?而不會指向其他物件的Transform? 這是因為,我們這個腳本是直接套用在Player上面的,如果沒有特別撰寫,就是直接抓取被套用的該物件的元件。 如果有需要在這個腳本抓取其他物件的元件,那會有進一步的作法,我們之後有機會再來探討這方面的問題。 |
f.rigid = GetComponent<Rigidbody2D>(); 這行與e.相同,就是將rigid變數指向Player的Rigidbody 2D元件。 ※由於e.與f.都是將一開始宣告的變數指定給欲控制的元件,屬於初始值宣告的一種,所以會習慣放在Start()方法裡。 |
g.void Update () 這行也是預設好的程式碼,這點與d.一樣,不過,「Update ()」方法,是會在遊戲中的每一幀都執行一次,所以這裡面的程式,在遊戲中每一分每一秒都會被執行。它會持續不斷的執行這個方法裡面的程式。 所以,如果在遊戲中有需要判斷時間的地方,大多都會被寫在這裡。 |
h.if (Input.GetKey(KeyCode.LeftArrow)) 這一行是判斷式,整行的描述用口語來解釋就是:「如果玩家按著左方向鍵......」 if應該不用解釋,這就是條件判斷的起點。 Input.GetKey的回傳值是布林值,用來判斷玩家按住按鍵的狀態,如果按著,就回傳true,反之就回傳false。 這點在Unity API也會有寫哦。 但是,判斷玩家按著按鍵,是按著甚麼按鍵呢?在GetKey()的括弧裡面,我們可以放上「KeyCode.按鍵名稱」來指定判斷的按鍵。 我在這裡使用了「LeftArrow」,來指定判斷的按鍵是左方向鍵。 ※其實Input.GetKey有很多兄弟姊妹,它有許多類似的函數,可能會隨著遊戲需求不同而有不同的寫法,我順便趁這個機會介紹一下 (1)Input.GetKey:就是我們所使用的這種,判斷為「按著」按鍵時。 (2)Input.GetKeyDown:這是只有在按鍵按下去的那一瞬間,判斷為「按下」按鍵時。 (3)Input.GetKeyUp:這是只有在放開按鍵的那一瞬間,判斷為「放開」按鍵時。 |
i.trans.Translate(Vector2.left * Time.deltaTime); 這一行開始要透過trans來控制物件的位置了。 Translate()是用來移動物件的方法。括弧內需要放入向量型別的數值。我在裡面放入了Vector2.left。 Vector2是一種2D的向量型別,我直接用它原本就擁有left方法,讓這個物件朝向左邊移動。 Vector2.left其實就是向量座標(-1,0) 照上述所說,那麼trans.Translate(Vector2.left)不就可以讓物件向左移動了嗎?那後面那一串Time.deltaTime是甚麼? Time.deltaTime是遊戲中每一幀所經過的時間,如果直接用trans.Translate(Vector2.left)來控制物件移動,那麼物件每幀移動的距離會非常大、移動速度會非常快。所以我需要把它乘以遊戲中每一幀經過的時間,把他的數值縮小,好讓它能夠在每一幀移動「與每幀經過時間相同的數值」的距離。 如果還是不懂,可以偷偷把Time.deltaTime刪掉然後試玩看看XDD |
j.else if (Input.GetKey(KeyCode.RightArrow)) 概念與h.相同,只是將LeftArrow改成了RightArrow。 我會將左右鍵的判斷寫在同一個if裡面,是為了避免左右鍵一起按造成主角無法移動的現象。 |
k.trans.Translate(Vector2.right * Time.deltaTime) 概念與i.相同,也只是將left改成了right。 |
l.if (Input.GetKeyDown(KeyCode.UpArrow)) { 這裡與h.j.不一樣的地方是,我把GetKey改成了GetKeyDown。 在g.有提過,Update()方法裡面的程式,會在每一幀都被執行,所以如果我的判斷是「按著」方向鍵(GetKey)的話,那主角就不會有跳躍的感覺,而是只要玩家一直按著,主角就會不斷的往天空飛。這並不是我們想要的效果。 GetKeyDown,會讓判斷專注在「按下的那一瞬間」。所以不管玩家有沒有按著,只要有按下去,就只會執行一次。這才是我們希望有的效果。 |
m.rigid.AddForce(Vector2.up * 200); 這一行是透過rigid來控制Rigidbody 2D元件。 AddForce,增加力。是Rigidbody2D裡的方法,功用是針對這個物件,讓他擁有無形的「力」 在剛剛c.宣告Rigidbody 2D變數的時候,有提到「跳躍」這個動作是讓角色能夠「抵抗重力」而向上的力道。 所以我們需要用這個方法,讓玩家擁有一個「往上」的無形的「力」。 於是,我們在AddForce()方法的括號中,加上剛剛學會的Vector2.up,來指定這個「力」的方向。 至於後面的 * 200,可以任意調整,如果想讓玩家跳高一點,就把數值調高,反之則然。 |
很好,現在我們的主角可以被我們的方向鍵控制左右行走、跳躍了。我們只剩做後一個步驟。
──讓攝影機隨著玩家移動。
這個步驟其實相當簡單,在沒有任何其他要求的情況下,只要把「Main Camera」物件丟到「Player」下面就好。像這樣:
現在,點擊Play試玩遊戲,攝影機是不是緊緊跟著主角不放阿XD?
最後,再來做完成的確認:
今天把較為基礎的程式方面的問題釐清了。
我們已經了解該怎麼用程式控制元件,也了解了Start()與Update()的差別。
懂得如何判斷按鍵,以及按鍵狀態的各種寫法。
最簡單的連結大致上都了解了。我們在程式這方面的教學也告一段落。
下一節將會是這一章的最後一節。我會說明該怎麼把做好的遊戲匯出成執行檔,並且打包給其他朋友遊玩。
那麼,這次的教學到此結束,我們下次再見!
========================================================================
【新手入門】
四、用程式操控物件&程式說明