想必經過之前的兩個教程,都已經能夠成功的製作出一個具備
- 刷怪功能
- 尋路功能
- 建塔功能
- 交互界面
的塔防類遊戲了。當然這樣是遠遠不夠的,今天的教程就要對之前的遊戲做一個優化。
隨機怪物
真正的塔防遊戲中,不會像現在這樣,怪物一個接一個的出來,應該是成批次,一波一波的出現,而且每一波都應該有不一樣的怪物。
這裏就涉及到兩個問題
間隔成批覆制mMonster
隨機生成怪物種類
第一點,我們可以回顧一下我們現在採用的策略。
當前的遊戲中,我們使用了Invoke函數來重複調用函數。我們的腳本是這樣寫的。
InvokeRepeating("MonsterFactory", 1, 3f);
1s執行三次MonsterFactory(複製Monster對象)的函數。
那其實照理說來我們已經實現了一批一批的出現怪物,只不過每一批都只出現一次,而且時間間隔爲1/3s很容易讓人有一種流水線的錯覺。
爲了改變這一點我們可以在MonsterFactory做一點手腳。讓他做一個循環。
<span style="font-size:14px;">void MonsterFactory() {
for(int i =0;i<5;i++) MonsterTemp = Instantiate(Monster, startp.transform.position, Quaternion.identity) as GameObject;
}</span>
這樣的話,每一批出來的怪物就都是5個了!當然爲了密集恐懼症的患者着想,我建議大家把Invoke的頻率調低....
然後就有讀者要扔板磚上來了!哪裏有成批量的怪物啊!和以前不是一毛一樣嗎!
稍安勿躁,請仔細看Hierarchy欄,我們的怪物數量的的確確是變多了的,只不過他們一個不小心,重疊在了一起...
解決的辦法我們之前已經在建立炮臺的時候使用過了,給Instantiate的的二個參數添加一個X軸的偏移量new Vec3(i,0,0);
當然每一波都出來兩個也是太過於無聊了。我們乾脆用一個隨機函數,讓他每一次生成的數量都不一樣。這裏要使用到Rand隨機變量,最後我們的代碼如下
<span style="font-size:14px;">void MonsterFactory() {
for (int i = 0; i < Random.Range(1,5); i++)
{ MonsterTemp = Instantiate(Monster, startp.transform.position+new Vector3(i,0,0), Quaternion.identity) as GameObject; }
}</span>
每一次都能出現1-5個怪物(是不是很豪華呢!!!)
計分系統
作爲一個遊戲,一定要有分數的對吧。
說到分數,大家第一時間想到的肯定是上一次Roll a Ball的GUI Text.傳送門點我
當然有的人就是懶得戳鏈接,我們這裏再重複一遍步驟
首先我們需要在Hierarchy列表中增加兩個GUI text,作爲顯示分數用的文本和用來顯示失敗的文本。
塔防遊戲中一項計分規則是:
當敵人沒有被打死,走道了盡頭時,玩家的生命值就會減一。我們先來做這個生命值減少的分數。
打開CreateTower腳本(因爲在這裏我們有了GUI所以就把計分系統也扔到這裏來。
新建兩個Public變量,用來掛載GUItxt組件。我們分別叫做scoreTxt和loseTxt。
由於scoreTxt是用來顯示剩餘生命值的,所以我們還需要一個float 型的score來實時更新。
代碼如下
<span style="font-size:14px;"> public GUIText loseTxt;
public GUIText scoreTxt;
public float score;
// Use this for initialization
void Start () {
score = 10;
loseTxt.enabled = false;
}</span>
將score初始化爲0,並且讓Lose默認不可見然後呢,score的減少應該在monster經過終點,被銷燬的時候調用,找到那段代碼。
這裏有一個問題,我們的score是當前腳本的變量,如何在另一個腳本中調用呢。我們這裏採取的方案如下
if (Vector3.Distance(wayPoint.GetChild(1).position, transform.position) < 1.0f)
{
Destroy(gameObject);
GameObject.Find("Main Camera").GetComponent<CreateTower>().score--;
}
因爲Unity中,腳本也被視爲組件,所以你可以通過查詢組件來獲得腳本的public變量。
當然你也可以將變量聲明爲static型,就可以在別的腳本中調用了
score被更新之後,我們需要一個函數來實時把score傳入scoreTxt中,這個函數寫在CreateTower腳本中
void UpdateScore()
{
scoreTxt.text = "Left life:"+score.ToString();
if (score < 0)
{
scoreTxt.enabled = false;
loseTxt.enabled = true;
}
}
(在分數低於0之後讓scoretxt不可見,讓loseTxt可見)這樣我們就得到了一個比較完整的計分系統。(=====好吧我又在騙人了.....)
完整的積分系統應該包括另一個東西,那就是擊殺後得分。
但是由於筆者要出門遊玩,所以擊殺後得分這一塊下週回來給大家補全~~