昨天我們測試角色飛行的動畫的時候發現一些小問題:每次在動畫切換的時候他都會等一段時間才切換動畫,不會在墜落的時候立即切換墜落的動畫。想要解決這個問題,我們只要點選動畫之間 Transition 的箭頭,把 Has Exit Time 取消打勾,並且設置所有的過度動畫時間為 0 就可以解決這個問題了
解決了上次的問題,今天我們要來製作水管和地板的移動!讓角色看起來像是在往前飛一樣。
Tube
,再從 Prefab
拉兩根水管到這個空物件中,順便調整一下方向和位置BoxCollider
,這樣小鳥也會與這些水管發生碰撞。需要注意的是,我們還要在包著兩個水管的空物件上也加上 BoxCollider
,同時把 is Trigger 的選項打勾,這個 BoxCollider
就成為了一個觸發器。觸發器不會與物體發生真實的碰撞反應(也就是會直接穿過去),但可以通過函式來偵測碰撞的行為是否發生,這可以用於加分的機制框框內的長方條就是碰撞器的觸發範圍,上下兩個是水管的
BoxCollider
我們建立一個讓水管移動的腳本,命名為 Tube.cs
// Tube.cs
using UnityEngine;
public class Tube : MonoBehaviour
{
[SerializeField] private float moveSpeed;
private void Update()
{
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
}
}
這裡的 transform.Translate()
表示位移的意思,而裡面要填入的是一個三為向量,Vector3.forward
表示向 z 軸( 0, 0, 1)的方向移動。
執行遊戲之後水管就會自己移動了
但是我們不希望水管無限往後移動,這樣會造成資源的浪費,所以我們要在水管移出範圍之後自動刪除
// Tube.cs
using UnityEngine;
public class Tube : MonoBehaviour
{
[SerializeField] private float moveSpeed;
[SerializeField] private float zBound;
private void FixedUpdate()
{
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
if(transform.position.z <= zBound)
{
Destroy(gameObject);
}
}
}
我們創建了一個 zBound
變數,當水管的 z 座標超過 zBound
時,我們就使用 Destroy(gameObject)
來刪除這個物件。
當物件超出我們設定的範圍時就會自動被刪除
我們可以把這兩個水管也做成 Prefab ,方便之後的水管生成
為了能夠隨機的生成水管,我們需要在場景中有一個物件上面掛著能夠操控這些水管生成,所以我們再創立一個空物件(Create Empty),取名為 TubeSpawner.cs
// TubeSpawner.cs
using UnityEngine;
public class TubeSp : MonoBehaviour
{
[SerializeField] private Tube tubePrefab;
[SerializeField] private float spawnMaxY;
[SerializeField] private float spawnMinY;
private void SpawnTube()
{
Vector3 spawnPos = new Vector3(transform.position.x, Random.Range(spawnMinY, spawnMaxY), transform.position.z);
Instantiate(tubePrefab, spawnPos, Quaternion.identity);
}
}
我們宣告了 Tube
的物件,方便之後的生成。接下來在 SpawnTube()
中先宣告一個 Vector3
,把我們生成的位置填入,例如這邊的 Random.Range(spawnMinY, spawnMaxY)
就表示在 spawnMinY
和 spawnMaxY
之間隨機選一個數。之後就可以套用到 Instantiate()
裡面將水管稱成囉
把
TubeSpawner
這個空物件放到水管要生成的地方
但現在執行遊戲不會發生任何事情,因為我們沒有呼叫這個生成水管的方法
為了每隔固定一段時間生成水管,我們需要製作一個計時器
// TubeSpawner.cs
using UnityEngine;
public class TubeSp : MonoBehaviour
{
[SerializeField] private Tube tubePrefab;
[SerializeField] private float spawnMaxY;
[SerializeField] private float spawnMinY;
[SerializeField] private float spawnTime;
float timer = 0f;
private void Update()
{
timer += Time.deltaTime;
if(timer >= spawnTime)
{
timer = 0f;
SpawnTube();
}
}
private void SpawnTube()
{
Vector3 spawnPos = new Vector3(transform.position.x, Random.Range(spawnMinY, spawnMaxY), transform.position.z);
Instantiate(tubePrefab, spawnPos, Quaternion.identity);
}
}
我們宣告一個 timer
並讓他每次 Update()
的時候都加上 Time.deltaTime
,也就是經過的時間。只要 timer
大於我們的 spawnTime
,我們就呼叫 SpawnTube()
!這樣就完成了一個簡單的計時器
執行遊戲後,水管就會每隔一段時間生成囉!
如果單單只有水管在移動,還是少了點鳥在往前飛的感覺,所以我們要來讓地板也會跟著水管向前
我們複製一塊地板並把他往前拉,我們要創立一個新的腳本,取名為 Floor.cs
來控制這個地板,當地板超過邊界值的時候就把地板的位置設定到最開始,來達成無限地板的效果。
再執行遊戲就能看到地板和水管一起向後移動囉!並且地板會在超出範圍之後自動向後移動。
今天完成了水管移動、水管生成和地板移動的部分,明天我們要來添加計分還有Game Over 的機制!