11 游戲流程控制
使用協程來控制游戲流程
11.1 添加MessageText
首先添加一個Text來顯示文字
設置GameMgr
11.2 游戲整體流程

下面GameMgr.cs最終代碼預覽,后面我們逐個講解.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class GameMgr : MonoBehaviour
{
private int roundNumber = 0; // 輪次. public Text messageText; // ui text private bool gameOver = false; // 本輪游戲是否已結束 // Use this for initialization void Start () { StartCoroutine ( GameLoop ()); } private IEnumerator GameLoop () // 游戲主循環邏輯 { yield return StartCoroutine (RoundStart ()); // 開始本輪游戲. yield return StartCoroutine (RoundPlay ()); // 游戲進行中. yield return StartCoroutine (RoundEnd ()); // 本輪游戲結束. StartCoroutine (GameLoop ()); // 開始下一輪游戲 } private IEnumerator RoundStart () { roundNumber++; // 累計輪數 messageText.text = "ROUND " + roundNumber; yield return new WaitForSeconds (2f);// 等待2s繼續 } private IEnumerator RoundPlay () { messageText.text = string.Empty; // 清空 "GamePlaying";// while (!gameOver) // 游戲結束才跳出 { yield return null; } } private IEnumerator RoundEnd () { string message = "GameEnd"; // 顯示分數 messageText.text = message; yield return new WaitForSeconds (2f);// 等待2s繼續 }}
11.3 開始本輪游戲 RoundStart()
開始新一輪游戲是需要做三件事情
ResetTanks (); // 重置坦克
DisableTanksControl (); // 禁用坦克操作
camera.SetStartPositionAndSize ();// 重置相機
為了方便對坦克進行操作,我們寫了TankMgr來實現對於坦克的控制。
TankMgr.cs
using UnityEngine;
using System.Collections;
public class TankMgr : MonoBehaviour {
public Transform spawnPoint; // 出生點 public void Reset(){// 重置坦克 transform.position = spawnPoint.position;//坐標 transform.rotation = spawnPoint.rotation;//旋轉角度 GetComponent<Health> ().blood = 100;//血值 } public void EnableControl(){// 啟用控制 GetComponent<TankMove> ().enabled = true; GetComponent<TankShoot> ().enabled = true; } public void DisableControl(){ // 禁用控制 GetComponent<TankMove> ().enabled = false; GetComponent<TankShoot> ().enabled = false; }}
還需要設置兩個GameObject作為SpawnPosition
TankMgr是直接掛載到Tank上面的
最終RoundStart()函數里面是這樣的
private IEnumerator RoundStart ()// 開始本輪游戲.
{ ResetTanks (); // 重置坦克 DisableTanksControl (); // 禁用坦克操作camera.SetStartPositionAndSize ();// 重置相機
roundNumber++; // 累計輪數 messageText.text = "ROUND " + roundNumber; yield return new WaitForSeconds (2f);// 等待2s繼續 }
因為要控制所有坦克,所以需要一個數組保存所有坦克。
public TankMgr[] tanks; // 所有坦克
private void ResetTanks(){ // 重置坦克狀態
foreach( TankMgr tm in tanks) tm.Reset();}
private void DisableTanksControl(){ // 禁用坦克操作
foreach( TankMgr tm in tanks) tm.DisableControl();}
然后當游戲開始的時候重新起來坦克控制
IEnumerator RoundPlay(){
foreach( TankMgr t in tanks){ t.EnableControls (); } messageText.text = "Playing"; while( true ){// 一直運行,直到有一個坦克掛掉 yield return null; } }
這是游戲處理運行過程,我們需要判斷什么時候有坦克已經掛掉.
這時候我們發現按照之前在Health.cs里面的處理,坦克是直接被Destroy掉的.所以這個地方我們做一些調整.當坦克掛掉之后,我們把它SetActive(false)
public void TakeDamage( float damage){
currentBlood -= damage; // 掉血 slider.value = currentBlood; // 更新血槽顯示 if (currentBlood <= 0) { // die //ps.transform.parent = null; ps.Play (); audioSource.clip = explosionAudio; audioSource.Play (); //Destroy (ps.gameObject, ps.duration); //Destroy (gameObject); gameObject.SetActive ( false ); } }
這樣當坦克掛掉之后並不是真的把它銷毀了,我們可以使用gameObject.activeSelf來判斷坦克是否已經掛掉
bool OneTankLeft(){ // 判斷是否有坦克掛掉
foreach( TankMgr t in tanks){ if (t.gameObject.activeSelf == false) return true; } return false; }
這樣我們就可以終止RoundPlay里面的while語句了
IEnumerator RoundPlay(){
foreach( TankMgr t in tanks){ t.EnableControls (); // 啟用坦克控制 } messageText.text = ""; while( !OneTankLeft() ){// 一直運行,直到有一個坦克掛掉 yield return null; } }
這樣程序就可以執行到下一個階段,就是RoundEnd函數里面了.
在游戲結束的時候我們需要知道玩家到底是誰,所以我們什么一個winner來保持贏家
private int winner; // 贏家
int GetWinner(){ // 誰是贏家
for(int i=0;i<tanks.Length;i++){ if (tanks [i].gameObject.activeSelf == true) return i; } return 0; }
這個方法在如果有一個坦克掛掉的時候就返回此坦克在Tanks數組中的索引.如果兩個坦克都掛掉了(是有這種可能的),現在返回的仍然是0,可以返回一個-1,單獨處理,這個我們在這就不講了,大家下去自己實現一些.
IEnumerator RoundEnd(){ // 本輪游戲結束
winner = GetWinner (); messageText.text = "Player "+(winner+1)+" wins!";// 顯示贏家 yield return new WaitForSeconds (2f); }
這樣游戲就可以一輪一輪的進行下去了,如果我們想在某一輪后結束游戲,可以判斷roundNum來實現.
---------------------------我是目錄分割線---------------------------
《杜增強講Unity之Tanks坦克大戰》4-坦克的移動和旋轉
《杜增強講Unity之Tanks坦克大戰》9-發射子彈時蓄力
《杜增強講Unity之Tanks坦克大戰》11-游戲流程控制
---------------------------我是目錄分割線---------------------------
