1. 程式人生 > >[Unity3D]Unity3D遊戲開發之飛機大戰專案講解

[Unity3D]Unity3D遊戲開發之飛機大戰專案講解

        首先感謝大家對我部落格的關注,今天我想和大家分享的是一個飛機大戰的專案。這是一個比較綜合的專案,希望對大家學習Unity3D有所幫助,我會在文章最後給出專案程式碼。作為一個遊戲而言,遊戲策劃十分重要,所以在開始今天的文章之前,我們先來了解下這個專案的策劃。我們的玩家是一個飛機,玩家可以使用A、D、S、W四個鍵位來控制飛機位置,當按下空格鍵時,我方飛機可以向敵機發射炮彈,當敵機中彈後將減少生命值,當敵機生命值為0時,敵機將爆炸銷燬。在遊戲場景中只有一種從螢幕上方不斷向下飛行的敵機,當我方飛機與敵機碰撞後,雙方都將減少生命值。當我方生命值減少至0時,遊戲將結束。好了,瞭解完遊戲規則設定後,我們就可以開始今天的內容了。

    一、遊戲場景


      我們這裡在場景中新增GUIText物件來顯示玩家得分等基本資訊,指令碼定義如下:

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
	
	//玩家得分
	private Transform Grade;
	//玩家生命
	private Transform HP;
	//遊戲結束
	private Transform Text;
	//玩家
	private GameObject Player;
	
	void Start ()
	{
	  //初始化介面
	  Grade=transform.Find("Grade");
	  HP=transform.Find("HP");
	  Text=transform.Find("Text");
	  Text.guiText.enabled=false;
	  //獲取玩家物件
	  Player=GameObject.Find("Player");
	}
	
	void Update () 
	{
	  if(Player!=null)
	  {
	    //更新UI
	    Grade.guiText.text="得分:"+Player.GetComponent<Player>().Grade.ToString();
	    HP.guiText.text="生命:"+Player.GetComponent<Player>().MaxHP.ToString();
	  }
	  if(HP.guiText.text=="生命:0")
	  {
		 Text.guiText.enabled=true;
		 //立即復活
	     if(Input.GetKey(KeyCode.Y))
		 {
			Application.LoadLevel("Main");	
		 }
		 //退出
		 if(Input.GetKey(KeyCode.N))
		 {
			Application.Quit();
		 }
	  }
	}
}


      二、玩家飛機

      玩家飛機的建立和背景的建立時相同的,這裡我們不再多說。玩家飛機需要完成移動、發射、碰撞的事件處理。為此我們編寫下面的指令碼:

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

    //飛機的移動速度
    public float MoveSpeed;
    //飛機的最大生命值
    public int MaxHP=100;
    //定義子彈物件
    public GameObject Bullet;
    //定義子彈發射位置
    private Transform BulletPosL;
    private Transform BulletPosR;
    
	[HideInInspector]
	public int Grade=0;
	
	void Start () 
	{
	  BulletPosL=this.transform.Find("BulletPosL");
	  BulletPosR=this.transform.Find("BulletPosR");
	}
	
	void Update () 
	{
	  if(Input.GetKey(KeyCode.A))
	  {
	     transform.Translate(Vector3.left*Time.deltaTime*(-MoveSpeed));
	  }
	  if(Input.GetKey(KeyCode.D))
	  {
	     transform.Translate(Vector3.left*Time.deltaTime* MoveSpeed );
	  }
	  if(Input.GetKey(KeyCode.W))
	  {
	     transform.Translate(Vector3.forward*Time.deltaTime*(-MoveSpeed));
	  }
	  if(Input.GetKey(KeyCode.S))
	  {
	     transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
	  }
	  //按下空格鍵,發射子彈
	  if(Input.GetKey(KeyCode.Space))
	  {
	     Instantiate(Bullet,BulletPosL.transform.position,Quaternion.Euler(new Vector3(0,1,0)));
	     Instantiate(Bullet,BulletPosR.transform.position,Quaternion.identity);
	  }
	}
	
	#region 減血
	public void Hit(int Value)
	{
	   if(MaxHP>0)
	   {
	     MaxHP-=Value;
	   }else
	   {
		 Destroy(this.gameObject);
	   }
	}
	#endregion
	
	#region 增加分數 
	public void Add(int Value)
	{
		Grade+=Value;
	}
	#endregion

}

       在這段程式碼中,Bullet是我們的子彈物件,它從飛機的兩個子彈發射位置BulletPosL、BulletPosR發射,向螢幕上方按照一定的速度緩緩移動,當子彈與敵人碰撞時,子彈物件將銷燬,同時敵人生命值減少。Bullet物件對應於我們的一個Prefab。BulletPosL、BulletPosR對應于飛機上的兩個位置。如圖:


      我們的子彈Bullet是一個綁定了指令碼的Capsule。它的程式碼定義如下:

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {
	
	//定義子彈的移動速度
	public float MoveSpeed=10F;
	//定義子彈的銷燬時間
	public float DestroyTime=2.0F;
	//定義子彈對敵人的傷害值
	public int Damage=2;
	//玩家飛機
	private GameObject Player;
	
	void Start()
	{
		Player=GameObject.Find("Player");
	}
	void Update () 
	{
	   //移動子彈
	   transform.Translate(Vector3.up * MoveSpeed * Time.deltaTime);
	}
	
	//碰撞事件捕捉
	void OnTriggerEnter(Collider mCollider)
	{
		if(mCollider.gameObject.tag=="Enemy")
		{
			//敵人減血
			mCollider.gameObject.GetComponent<Enemy>().Hit(Damage);
			//我方得分
			Player.GetComponent<Player>().Add(1);
			//銷燬子彈
			Destroy(this.gameObject);
		}
	}

     //當離開攝像機範圍時觸發銷燬事件
	void OnBecameInvisible()
	{
	  Destroy(this.gameObject);
	}
}

   三、敵人飛機

在我們的遊戲中共有三種敵機,我們先將它們製作成預設。然後通過敵機生成器不斷地生成敵機。如圖:


 和子彈相反,我們希望敵機從螢幕上方以一定速度向下移動,當碰到玩家飛機或者子彈時,將減少生命值。為此,我們這樣定義敵機的指令碼:

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

	//移動速度
	public float MoveSpeed=1.5F;
	//爆炸
	public GameObject Explosion;
	//最大生命值
	public int MaxHP=100;
	
	
	void Update () 
	{
	  //移動飛機
	  transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
	}
	
	public void Hit(int Value)
	{ 
	  //如血量不低於0,則敵人飛機掉血
	  if(MaxHP>0)
	  {	
	     MaxHP-=Value;
	  }else
	  {
		 //產生爆炸效果
         Instantiate(Explosion,transform.position,Quaternion.Euler(new Vector3(90,180,0)));
		 //銷燬敵機
		 Destroy(this.gameObject);
	  }
    }
	
	void OnTriggerEnter(Collider mCollider)
	{
	  //如果與玩家飛機遭遇,則雙方減血
	  if(mCollider.gameObject.tag=="Player")
	  {
		 //敵機掉血
		 this.Hit(2);
		 //玩家飛機掉血
		 Transform mPlayer=mCollider.gameObject.transform.Find("Player");
		 mPlayer.GetComponent<Player>().Hit(2);
	  }
	}
	
	
	void OnBecameInvisible()
	{
	  Destroy(this.gameObject);
	}
}
      接下來,我們通過敵機生成器來不斷地生成敵機。敵人生成器是我們預製在遊戲場景中的空遊戲體,它位於遊戲場景的頂部。我們將下面的指令碼繫結到遊戲生成器 上,使其可以不斷地生成敵人:
using UnityEngine;
using System.Collections;

public class SpawnEnemy : MonoBehaviour {
	
	//定義敵人速度
	public float SpawnTime=1.0f;
	//定義敵人物件陣列
	public GameObject[] Enemys;
	
	void Start () 
	{
	   StartCoroutine("Spawn");
	}
	
	//通過迭代器生成敵人
	IEnumerator Spawn()
	{
	   //等待
	   yield return new WaitForSeconds(SpawnTime);
	   //克隆物件
       Instantiate(Enemys[Random.Range(0,3)],new Vector3(transform.position.x * Random.Range(-1F,1F),
			transform.position.y,-4),Quaternion.Euler(new Vector3(90,180,0)));  
	   StartCoroutine("Spawn");
	}
	
}
      其中Enemys對應到我們的敵人預設,每隔一段時間,我們隨機地產生一種敵人,該敵人將從螢幕上方緩緩向下移動。

    四、碰撞檢測

在這個遊戲中,主要存在子彈與敵機的碰撞、玩家飛機與敵機的碰撞兩種形式。它們分別被定義在Bullet.cs和Enemy.cs兩個類檔案中。

//碰撞事件捕捉
	void OnTriggerEnter(Collider mCollider)
	{
		if(mCollider.gameObject.tag=="Enemy")
		{
			//敵人減血
			mCollider.gameObject.GetComponent<Enemy>().Hit(Damage);
			//我方得分
			Player.GetComponent<Player>().Add(1);
			//銷燬子彈
			Destroy(this.gameObject);
		}
	}
void OnTriggerEnter(Collider mCollider)
	{
	  //如果與玩家飛機遭遇,則雙方減血
	  if(mCollider.gameObject.tag=="Player")
	  {
		 //敵機掉血
		 this.Hit(2);
		 //玩家飛機掉血
		 Transform mPlayer=mCollider.gameObject.transform.Find("Player");
		 mPlayer.GetComponent<Player>().Hit(2);
	  }
	}
     

 五、爆炸特效

     當敵機被摧毀時,將顯示爆炸特效,我們這裡採用一組2D貼圖來實現爆炸特效,原理是改變貼圖的mainTextureScale和mainTextureOffset兩個屬性值。我們來一起看程式碼:

using UnityEngine;
using System.Collections;

public class Explosion : MonoBehaviour {
	
	//動畫序列索引
	private int index=0;
	//聲音
	private AudioSource mAudio;
	
	void Start()
	{
	   mAudio=GetComponent<AudioSource>();
	}
	
	void FixedUpdate () 
	{
	   if(index<8)
	   {
		 this.renderer.sharedMaterial.mainTextureScale=new Vector2(1.0F/8,1);
		 this.renderer.sharedMaterial.mainTextureOffset=new Vector2(index * 1.0F/8,0);
		 index+=1;
	   }else
		{
		  mAudio.Play();
		  Destroy(this.gameObject);
		}
	}
}
     其中mAudio對應到一個AudioSource元件,我們在這裡指定一個爆炸的音效。同樣地,我們將爆炸製作成預設,該預設對應於Enemy.cs中的Explosion。

     好了,到這裡今天的 內容就講解完了,我們一起來看看最終的效果吧!


     希望今天的內容大家能夠喜歡。學了這麼長時間的Unity3D,感慨還是挺多的,很多東西你不努力去做,是永遠做不好的,你不給自己壓力,你不會知道自己有多優秀。本專案原始碼可以從這裡下載。

 每日箴言: 不管活到什麼歲數,總有太多思索、煩惱與迷惘。一個人如果失去這些,安於現狀,才是真正意義上的青春的完結。——  渡邊淳一


      喜歡我的部落格請記住我的名字:秦元培,我的部落格地址是blog.csdn.net/qinyuanpei
      轉載請註明出處,本文作者:秦元培,本文出處:http://blog.csdn.net/qinyuanpei/article/details/25158323