炫酷跑酷教程(2)——多樣化的道路生成與簡單UI

本文為跑酷教程的第二期,第一期傳送門如下:

繁華如夢:炫酷跑酷教程(1)——簡單的動態地圖生成與人物動作?

zhuanlan.zhihu.com圖標

地圖多樣化

在開始本篇教程之前,我們得先討論我們的跑酷遊戲中還需要什麼樣的地形,來豐富我們的地圖,完成地圖多樣化。那趕緊請出我的小夥伴給出創意啊:

夥伴A:地圖來個像斜坡的功能,能上能下,能右斜,左斜的那種。

夥伴B:總是在安全的地面跑太沒有挑戰了,加上鏤空的地圖多刺激。

目標地圖

由以上需求分析出我們新的地形生成:

地形1:上升地形

地形2:下降地形

地形3:左斜地形

地形4:右斜地形

地形5:陷阱地圖

地型實現

地形1-4生成比較簡單,只要在引導物體更換坐標時,改變下一次的相應方向的值就行。我們在GameMode.cs文件中新聲明地形的生成函數。如圖:

public void BuidUpTerrain() //生成上升地形 { var tmpRoad = Instantiate(roadTemplate, guideTrs.position, guideTrs.rotation); PlayRoadAnimator(tmpRoad); roads.Add(tmpRoad); guideTrs.position += guideTrs.forward; guideTrs.position += guideTrs.up * 0.1f; }

但是地形地圖需要連續一段才能看出效果,我們就設定任何一種地形都是至少由10個道路組成,值得注意的是,我們現在的地圖生成邏輯是踩過一個道路才會在生成下一個,如果這樣的話,我們生成地形地圖的時候就得注意道路生成的數量,否則就會造成遊戲生成物體的數量成指數級的增長,然後內存就爆掉了,這是血的教訓啊,一定要謹記。於是我們新加了限制條件,並做了如下更改:

public bool isBuidDirRoad; //是否生成方向道路 int dirRoadType; //方向道路的類型 int dirRoadNumber; //方向道路的數量 public void BuidRoad() //生成道路的方法 { if (isBuidDirRoad && dirRoadNumber > 0) { switch (dirRoadType) //通過道路的類型來進行生成 { case 1: BuidUpTerrain(); dirRoadNumber--; break; case 2: BuidDownTerrain(); dirRoadNumber--; break; case 3: BuidLeftTerrain(); dirRoadNumber--; break; case 4: BuidRightTerrain(); dirRoadNumber--; break; } if (dirRoadNumber <= 0) { isBuidDirRoad = false; } }

這樣就完成了我們的目標,限制了生成道路的數量。

地形5:陷阱地圖生成雖然較為簡單,只需要改變一下道路模板的自身旋轉,但是有3種模式,如下:

一:相對於道路的右邊

二:相對於道路居中

三:相對於道路右邊

知道了這幾種模式,我們就可以在代碼中進行實現,如下:

public void BuidTrapRoad() { guideTrs.position += guideTrs.forward; var tmpRoad = Instantiate(roadTemplate, guideTrs.position, guideTrs.rotation); var tmpController = tmpRoad.GetComponent<RoadController>(); tmpController.ChangeRoadType(); tmpRoad.transform.Rotate(Vector3.up,90); int trapType = Random.Range(1,4); //用於確定陷阱的相對位置--1左邊,2居中,3右邊! switch (trapType) { case 1: tmpRoad.transform.position += tmpRoad.transform.forward; break; case 2: //居中類型不做操作 break; case 3: tmpRoad.transform.position -= tmpRoad.transform.forward; break; } guideTrs.position += guideTrs.forward * 2.0f; PlayRoadAnimator(tmpRoad); roads.Add(tmpRoad); }

而且由於我們現在的旋轉函數是繞父物體的Fowrd軸旋轉的,改變父物體旋轉後,需要重新確定繞什麼軸進行旋轉。我們需要在RoadChildrenChange.cs文件中在寫一個旋轉函數。如下:

transform.RotateAround(parentObj.transform.position, parentObj.transform.right, 30 * Time.deltaTime);

金幣

沒有金幣這個道具,跑酷遊戲的色彩都會減少一半。在生成金幣的時候我們會發現,我們金幣生成的位置總是固定在道路的上方,每一個格子對應一個金幣的生成位,那麼按照這樣的邏輯,我們可以在道路生成完成後在進行金幣的生成,於是在RoadChildrenChange.cs中寫出我們的金幣生成函數:

private void Start(){ gold = Resources.Load("Gold") as GameObject; //讀取文件金幣的預製體 bool isCreat = Random.Range(1, 10) == 3 ? true : false; //是否生成金幣 if (isCreat) { Vector3 tmpPos = transform.position; gold = Instantiate(gold, tmpPos += transform.up * 1.2f, Quaternion.identity); gold.transform.SetParent(transform); nowQuat = gold.transform.rotation; //保存當前金幣的旋轉,方便初始化。 }}

在給金幣加上旋轉,這樣看起來就跟好玩了。

gold.transform.Rotate(Vector3.up,70*Time.deltaTime);

完成後:

UI

跑酷遊戲的UI不需要太多,我們這個工程暫時只做一個顯示當前金幣數的UI就足夠了。首先,我們新建一個Canvas,在Canvas下面新建一個Text的UI。打開2D視圖進行物體的位置改變。如圖:

完成創建以後,我們新建一個Goldcollision.cs文件,用來完成吃金幣的效果,代碼如下:

private void OnTriggerExit(Collider other) { var player = other.gameObject.GetComponent<PlayerController>(); if (player) { gameMode.goldNumber++; Destroy(gameObject); } }

接著將腳本掛載在金幣物體當中,並勾選觸發器按鈕,並保存。

同時我們在GameMode文件進行UI文本的更新:

using UnityEngine.UI; //引入UIprivate void Update() { numberText.text ="當前金幣數:"+ goldNumber.ToString(); }

場景裝飾

完成以上工作後,我發現之前的場景太low了,完全不符合我們的的遊戲主題,於是替換掉我們場景的天空盒子,更換道路材質,運行遊戲:

是不是頓時覺得高大上了許多呢?天空盒子與道路材質都可以在Unity的商店進行下載,導入後進行替換即可,這裡就不在過多闡述了。

結語

這期跑酷教程到此結束。工程鏈接和上期相同:

fanhuarumeng1314/RunProject

有心的同學可以發現,場景中大量的東西都是重複的。那麼有沒有一種方法能夠讓這些物體重複使用,降低內存的消耗呢?下面這篇文章可以幫到你:

陳虹松:【Unity】工具類系列教程——對象池!?

zhuanlan.zhihu.com圖標

末尾,還是打個廣告:

想學習遊戲開發的同學,歡迎來levelpp.com/圍觀。

推薦閱讀:

如何評價《夢幻西遊》這款遊戲?
防守和進攻,惰性(保守)策略和積極策略的思考
我的世界1.7.4中發射器怎麼做?
捕魚遊戲有哪些小技巧?
拇指玩是一款什麼樣的遊戲?

TAG:Unity遊戲引擎 | 遊戲開發 | 遊戲 |