Unity3D案例太空射擊(Space Shooter)流程介紹與程式碼分析(中)
阿新 • • 發佈:2019-01-27
(上)部分主要介紹了素材的新增以及基本的移動與涉及功能,這部分關注事件的實現(如碰撞檢測)。
傳送門:
太空射擊(Space Shooter)流程介紹與程式碼分析(中)
6.邊界的設定
在上述過程中,若一直髮射子彈,在Hierarchy中會一直出現子彈的程序,造成不必要的記憶體開銷。因此我們需要設定一個區域,用以檢測子彈是否出了邊界並將出邊界的子彈刪除。
為了實現邊界的設定,我們採用gameObject中的Cube進行邊界模擬,新建一個Cube,將Cube的Size設定成與背景相同的大小,並將Position參照Background進行設定。
之後,為邊界新建一個指令碼,用以銷燬邊界外的子彈,程式碼如下
新增完畢後,為了使隕石效果逼真,加入旋轉的功能,新建一個Script實現該功能 輸入
同理,我們可以多設定幾組隕石,在model中可見,方法同上。建立完畢後,將3個隕石模型放入Prefabs中。
8.子彈與隕石碰撞 為隕石建立一個指令碼 輸入
並將程式碼修改為
將兩個爆炸素材帶入即可實現
9.隨機建立隕石 開啟GameController,將控制程式碼如下寫入,實現隨機產生隕石的效果。
但此時的隕石會互相發生碰撞併發生爆炸,應改進。 10.建立一波又一波的隕石 這部分內容主要是在程式碼中進行修改,直接上程式碼
之後,為邊界新建一個指令碼,用以銷燬邊界外的子彈,程式碼如下
即可達成目標。 7.新增隕石 隕石的新增與子彈類似,新建一個gameObject(命名為Asteriod)再將model中的隕石拖入Asteriod,對Asteriod新增rigidbody和Capsule Colliderusing UnityEngine; using System.Collections; public class DestroyByBoundary : MonoBehaviour { void OnTriggerExit(Collider other) { Destroy (other.gameObject); } }
新增完畢後,為了使隕石效果逼真,加入旋轉的功能,新建一個Script實現該功能 輸入
即可完成隕石的旋轉操作。隕石的運動可以參照子彈的運動指令碼,將速度設定為負值即可。using UnityEngine; using System.Collections; public class RandmRotation : MonoBehaviour { public float tumble = 5f; // Use this for initialization void Start () { rigidbody.angularVelocity = Random.insideUnitSphere * tumble; //隕石的旋轉是隨機的 } }
同理,我們可以多設定幾組隕石,在model中可見,方法同上。建立完畢後,將3個隕石模型放入Prefabs中。
8.子彈與隕石碰撞 為隕石建立一個指令碼 輸入
即可 但上述程式碼存在問題,即隕石已經在Boundary中,在產生隕石的瞬間就能觸發OnTriggerEnter,因此直接就被銷燬。因此我們需要設定不同的Boundary以解決以上問題。using UnityEngine; using System.Collections; public class DestroyByCotact : MonoBehaviour { void OnTriggerEnter (Collider other) { Destroy (other.gameObject); Destroy (this.gameObject); } }
並將程式碼修改為
if (other.gameObject.tag == "Boundary") //若隕石在邊界之中,什麼也不做。
{
return;
}
即可,此時子彈就可正常與隕石進行碰撞並銷燬。(需保證子彈和隕石在同一個2D平面上)
為了保證遊戲反饋,我們需要新增爆炸效果讓玩家有一個直觀的視覺體驗。因此對程式碼進行修改如下。
using UnityEngine;
using System.Collections;
public class DestroyByCotact : MonoBehaviour {
public GameObject explosion;
public GameObject playerExplosion;
void OnTriggerEnter (Collider other) //只要打到了隕石,執行如下操作
{
if (other.gameObject.tag == "Boundary") //如果隕石碰到邊界,什麼也不做
{
return;
}
if (other.gameObject.tag == "Player") //如果碰撞的是玩家,銷燬飛機
{
Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
}
Destroy (other.gameObject);
Destroy (this.gameObject);
Instantiate (explosion, this.transform.position, this.transform.rotation); //銷燬隕石
}
}
即可,注意要將playership的Tag改成別的,方便指令碼中判斷。
將兩個爆炸素材帶入即可實現
9.隨機建立隕石 開啟GameController,將控制程式碼如下寫入,實現隨機產生隕石的效果。
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour {
public Vector3 spawnValue;
public GameObject[] hazards;
// Use this for initialization
void Start () {
Debug.Log("Spaceshooter begins!!!");
}
// Update is called once per frame
void Update () {
if(Random.value<0.1) //Random.value隨機產生0~1的數,小於0.1表示十分之一的概率出現隕石
Spawn ();
}
void Spawn()
{
GameObject o = hazards [Random.Range (0, hazards.Length)]; //從3個隕石model中任選一個
Vector3 p = new Vector3 (Random.Range (-10, -2), spawnValue.y, spawnValue.z);//隕石隨機出現的區域要在邊界內,用Random.Range (-10, -2)限定
Quaternion q = Quaternion.identity; //i.e (0,0,0)
Instantiate (o, p, q);
}
}
即可,並將3種隕石放入hazards陣列內,即可實現。
但此時的隕石會互相發生碰撞併發生爆炸,應改進。 10.建立一波又一波的隕石 這部分內容主要是在程式碼中進行修改,直接上程式碼
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour {
public Vector3 spawnValue;
public GameObject[] Hazards;
public int numPerWave = 10;
public float gameStartTime = 2f; //遊戲開始的等待時間
public float waitTime = 1f; //每個隕石出現間隔
public float waveTime = 4f; //每一波的間隔
// Use this for initialization
void Start () {
Debug.Log("Spaceshooter begins!!!");
StartCoroutine (SpawnWave ());
}
// Update is called once per frame
void Update () {
// if(Random.value<0.1)
// Spawn ();
}
IEnumerator SpawnWave()
{
yield return new WaitForSeconds(gameStartTime);
while (true) //無限迴圈
{
for (int i=0; i<10; i++) //for迴圈實現每一秒出一個,10個為一波
{
Spawn ();
yield return new WaitForSeconds (waitTime);
}
yield return new WaitForSeconds(waveTime); //出完一波後的等待
}
}
void Spawn()
{
GameObject o = Hazards [Random.Range (0, Hazards.Length)];
Vector3 p = new Vector3 (Random.Range (-10, -2), spawnValue.y, spawnValue.z);
Quaternion q = Quaternion.identity; //i.e (0,0,0)
Instantiate (o, p, q);
}
}
即可
至此,基本功能已實現,為了提高遊戲的即時反饋,我們需要對遊戲進行完善,在(下)中進行介紹。