最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity快速上手系列之4:《塔防》終

2019-08-30 16:37 作者:皮皮關(guān)做游戲  | 我要投稿

作者:四五二十


大家好。都特么快把這個(gè)小項(xiàng)目忘了,趕緊把坑填上。


今天我們來為塔防做經(jīng)濟(jì)系統(tǒng)和升級(jí)功能,還是先看一個(gè)視頻:

為塔防做簡化的經(jīng)濟(jì)系統(tǒng)和升級(jí)功能


簡化的經(jīng)濟(jì)和升級(jí)系統(tǒng)如下:

我們?cè)诮ㄔ旌蜕?jí)防御塔時(shí)會(huì)消耗金錢;

每次消滅敵人時(shí)和出售防御塔會(huì)獲得金錢;

隨著防御塔級(jí)別的提升,升級(jí)所要消耗的金錢與出售時(shí)獲得的金錢也會(huì)逐步提高,且升級(jí)后的防御塔會(huì)獲得攻擊力等技能上的提升;

玩家進(jìn)入游戲時(shí)有一定數(shù)量的初始金錢。


根據(jù)上面的思路,本篇文章分為兩部分:經(jīng)濟(jì)系統(tǒng)的實(shí)現(xiàn)與防御塔升級(jí)系統(tǒng)的實(shí)現(xiàn)。


創(chuàng)建一個(gè)游戲數(shù)據(jù)類,主要存放金錢數(shù)據(jù):

public class GameData

{

??? private static GameData _Instance;

??? public static GameData Instance

??? {

??????? get

??????? {

??????????? if (_Instance == null)

??????????????? _Instance = new GameData();

??????????? return _Instance;

??????? }

??? }

??? //游戲金錢

??? public int gold;

}

?然后在主調(diào)類GameMain中初始化金錢:

??? public int InitGold;

??? //初始化游戲數(shù)據(jù)

??? void InitGameData()

??? {

??????? GameData.Instance.gold = InitGold;

??? }

?

在場景中搭建一個(gè)金錢顯示窗口:

實(shí)時(shí)顯示當(dāng)前金錢數(shù)

為它創(chuàng)建一個(gè)腳本:

public class GoldPanel : MonoBehaviour

{

??? public static GoldPanel Instance;

??? public Text goldText; //把顯示數(shù)量的Text拖進(jìn)去

??? //初始化

??? public void Init()

??? {

??????? Instance = this;

??????? //將當(dāng)前金錢顯示在界面上

??????? goldText.text = GameData.Instance.gold.ToString();

??? }

}

?

該初始化方法也放到GameMain中調(diào)用,但要放在初始化金錢后調(diào)用。

然后來到GameData類中,添加增加金錢和減少金錢的方法:


//增加金錢

public void AddGold(int _gold)

{

??? gold += _gold;

??? GoldPanel.Instance.goldText.text = gold.ToString();

}

//減去金錢

public void SubGold(int _gold)

{

??? gold -= _gold;

??? GoldPanel.Instance.goldText.text = gold.ToString();

}

?

由于我們會(huì)把升級(jí)系統(tǒng)放后面,所以現(xiàn)在我們就可以在建造防御塔時(shí)和消滅敵人時(shí)分別調(diào)用減少金錢和增加金錢,具體數(shù)量自定設(shè)定:

敵人腳本中添加增加金錢屬性:

public int gold; //金錢獎(jiǎng)勵(lì)

?

消滅敵人時(shí)調(diào)用:

GameData.Instance.AddGold(gold);


防御塔腳本中添加相應(yīng)屬性:

public int gold; //修建價(jià)格


在創(chuàng)建防御塔時(shí)調(diào)用:

GameData.Instance.SubGold(gold);


稍微修改一下防御塔的菜單界面:

將購買價(jià)格顯示在頭像上方

IconElement增加新屬性:

[SerializeField]

?private Text goldTxet; //將購買價(jià)格Text拖進(jìn)去


有了經(jīng)濟(jì)系統(tǒng)后,防御塔就不能無限建造了,如果金錢不夠則不能購買防御塔,我們的防御塔是通過拖拽Icon來購買的,在IconElement腳本中增加一個(gè)判斷方法:

?

//隱藏切換,發(fā)現(xiàn)金幣不足時(shí)頭像置灰,隱藏腳本(將不能點(diǎn)擊)

public void HideSwitch(bool enough)

{

??? if (enough)

??? {

??????? enabled = true;

??????? image.color = new Color(1, 1, 1); //頭像顏色正常

??????? goldTxet.color = new Color(1, 1, 1); //字體顏色正常

??? }

??? else

??? {

??????? enabled = false;

??????? image.color = new Color(0.5f, 0.5f, 0.5f); //頭像置灰

??????? goldTxet.color = new Color(1, 0, 0); //字體變紅

??? }

}

?

而Icon由PagodaMenu統(tǒng)一管理的,所以在PagodaMenu腳本中進(jìn)行統(tǒng)一判斷:


??? //刷新菜單,發(fā)現(xiàn)金錢不夠的就隱藏該菜單選項(xiàng)

??? public void RefreshMenu()

??? {

??????? for (int i = 0; i < icons.Length; i++)

??????? {

??????????? icons[i].HideSwitch(GameData.Instance.gold >= icons[i].gold);

??????? }

??? }

?

刷新菜單的方法放在金錢數(shù)量改變時(shí)調(diào)用即可:

PagodaMenu.Instanc.RefreshMenu();????

演示視頻

之前弓箭手的腳本Pagoda是防御塔類的基類,現(xiàn)在我們把基類單獨(dú)提出來,弓箭手重新掛上一個(gè)Pagoda1腳本來繼承Pagoda,把獨(dú)屬于弓箭手的屬性和方法放入Pagoda1中。

防御塔共設(shè)定了4個(gè)等級(jí),初始的0級(jí)到3級(jí),我們現(xiàn)在為Pagoda腳本增加幾個(gè)屬性:

public int grade; //當(dāng)前等級(jí)(隨等級(jí)變動(dòng))

[HideInInspector]

public int upgradeGold; //升級(jí)價(jià)格(隨等級(jí)變動(dòng))

[HideInInspector]

public int sellGold; //出售價(jià)格(隨等級(jí)變動(dòng))

?

不同的防御塔根據(jù)功能不同,升級(jí)的屬性也稍有不同:

這些升級(jí)屬性會(huì)在每次等級(jí)發(fā)生變動(dòng)時(shí)根據(jù)等級(jí)刷新,從上面表中總結(jié)出幾個(gè)相同的升級(jí)項(xiàng):升級(jí)價(jià)格,出售價(jià)格,攻擊力,我們?cè)赑agoda中創(chuàng)建刷新數(shù)據(jù)的方法,并在等級(jí)發(fā)生變動(dòng)時(shí)調(diào)用:

//根據(jù)等級(jí)更新數(shù)值

public virtual void UpdateByGrade()

{

}

//升級(jí)屬性

public void Refresh(int _upgradeGold, int _sellGold, float _damage)

{

??? upgradeGold = _upgradeGold; //升級(jí)升級(jí)價(jià)格

??? sellGold = _sellGold; //升級(jí)出售價(jià)格???????

??? damage = _damage; //升級(jí)攻擊力

}

?

在弓箭中腳本Pagoda1中實(shí)現(xiàn):

//根據(jù)等級(jí)更新數(shù)值

public override void UpdateByGrade()

{

??? switch (grade)

??? {

??????? case 0:

??????????? Refresh(10, 10, 30);

??????????? attactRange = 30; //升級(jí)攻擊范圍

??????????? break;

??????? case 1:

??????????? Refresh(20, 15, 40);

??????????? attactRange = 35;

??????????? break;

??????? case 2:

??????????? Refresh(30, 25, 50);

??????????? attactRange = 40;

??????????? break;

??????? case 3:

??????????? Refresh(0, 40, 60);

??????????? attactRange = 45;

??????????? break;

??? }

}

在錘子兵腳本Pagoda2中實(shí)現(xiàn):

float hammerRange; //擊飛范圍

//根據(jù)等級(jí)更新數(shù)值

public override void UpdateByGrade()

{

??? switch (grade)

??? {

??????? case 0:

??????????? Refresh(15, 15, 10);

??????????? hammerRange = 6; //升級(jí)擊飛范圍

??????????? break;

??????? case 1:

??????????? Refresh(30, 22, 12);

??????????? hammerRange = 8;

??????????? break;

??????? case 2:

??????????? Refresh(45, 37, 15);

??????????? hammerRange = 10;

??????????? break;

??????? case 3:

??????????? Refresh(0, 60, 20);

??????????? hammerRange = 12;

??????????? break;

??? }

}

?

在劍士腳本Pagoda3中實(shí)現(xiàn):

//根據(jù)等級(jí)更新數(shù)值

public override void UpdateByGrade()

{

??? switch (grade)

??? {

??????? case 0:

??????????? Refresh(20, 20, 50);

??????????? critChance = 0.2f; //升級(jí)暴擊率

??????????? break;

??????? case 1:

??????????? Refresh(40, 30, 65);

??????????? critChance = 0.3f;

??????????? break;

??????? case 2:

??????????? Refresh(60, 50, 80);

??????????? critChance = 0.4f;

??????????? break;

??????? case 3:

??????????? Refresh(0, 80, 100);

? ??????????critChance = 0.5f;

??????????? break;

??? }

}

?防御塔有了出售功能,意味著防御塔的模型可以重復(fù)利用,我們可以將防御塔也用對(duì)象池管理,在Pagoda中聲明對(duì)象池:


??? [HideInInspector]

??? public Transform pagodaPool; //對(duì)象池

?

在IconElement腳本中根據(jù)模型名字進(jìn)行初始化,創(chuàng)建過程中取消創(chuàng)建或出售時(shí)就返回對(duì)象池,并將該防御塔的等級(jí)清0,刷新數(shù)據(jù)。

(敵人那邊也可以加上對(duì)象池功能)

為Pagoda創(chuàng)建出售方法和升級(jí)方法:

//出售防御塔

public void SellPagoda()

{

??? GameData.Instance.AddGold(sellGold); //獲取金錢

??? //返回對(duì)象池,等級(jí)清0,刷新數(shù)據(jù)

??? transform.SetParent(pagodaPool);???????

??? grade = 0;

??? UpdateByGrade();

}

//升級(jí)方法

public void Upgrade()

{

??? //未滿級(jí)且金錢足夠才能升級(jí)

??? if (grade < 3 && GameData.Instance.gold >= upgradeGold)

??? {

??????? GameData.Instance.SubGold(upgradeGold); //減少金錢

??????? grade++;

??????? UpdateByGrade(); //升級(jí)后更新數(shù)值

??? }

}

?

使用UI搭建一個(gè)升級(jí)界面,加入出售和升級(jí)兩個(gè)按鈕,在添加兩個(gè)Text顯示出售價(jià)格和升級(jí)價(jià)格,并用三顆星星表示當(dāng)前等級(jí):

為它掛上一個(gè)腳本UpgradePanel:

public class UpgradePanel : MonoBehaviour

{

??? public static UpgradePanel Instanc; //單例

?

??? public Transform attRange; //攻擊范圍顯示器

??? [SerializeField]

??? private GameObject[] stars; //3顆星星

??? [SerializeField]

??? private Button gradebut; //升級(jí)按鈕

??? [SerializeField]

??? private Text sellGold; //顯示出售價(jià)格

??? [SerializeField]

??? private Text upgradeGold; //顯示出售價(jià)格

}

?

所要用到的元素在編輯器界面直接拖入:

創(chuàng)建初始化方法在GameMain中調(diào)用:

//初始化

public void Init()

{

??? Instanc = this;

??? gameObject.SetActive(false);

}

?

添加一個(gè)顯示防御塔信息的方法和刷新信息的方法:


Pagoda pagoda; //當(dāng)前防御塔,點(diǎn)擊防御塔時(shí)賦值

??? //顯示防御塔信息

??? public void ShowPagodaInfo(Pagoda _pagoda)

??? {

??????? gameObject.SetActive(true);

??????? pagoda = _pagoda;

??????? RefreshInfo();

??????? ShowattRange();

??? }

??? //根據(jù)等級(jí)刷新信息??

??? public void RefreshInfo()

??? {

??????? if (pagoda != null)

??????? {??? //顯示星星

??????????? for (int i = 0; i < stars.Length; i++)

??????????? {

??????????????? stars[i].SetActive(i < pagoda.grade);

??????????? }

??????????? sellGold.text = pagoda.sellGold.ToString(); //顯示出售數(shù)字

??????????? upgradeGold.text = pagoda.upgradeGold.ToString(); //顯示升級(jí)數(shù)字

?????????

??????????? Text butDes = gradebut.GetComponentInChildren<Text>();

?????????? //如果滿級(jí)或錢不夠

??????????? if (pagoda.grade >= 3 || GameData.Instance.gold < pagoda.upgradeGold)

??????????? {

??????????????? //按鈕為紅色,不能點(diǎn)擊

??????????????? butDes.color = Color.red;

??????????????? gradebut.enabled = false;

?

??????????????? if (pagoda.grade >= 3) //如果是滿級(jí)

??????????????? {

??????????????????? //數(shù)字隱藏

???????????????? ???upgradeGold.enabled = false;

??????????????? }

??????????????? else //不是滿級(jí),那就是錢不夠

??????????????? {

??????????????????? //數(shù)字顯示,為紅色

??????????????????? upgradeGold.enabled = true;

??????????????????? upgradeGold.color = Color.red;

??????????????? }

???? ???????}

??????????? else //未滿級(jí)且錢夠

??????????? {

??????????????? //數(shù)字顯示,為黃色

??????????????? upgradeGold.enabled = true;

??????????????? upgradeGold.color = Color.yellow;

??????????????? //按鈕為綠色,可以點(diǎn)擊

??????????????? butDes.color = Color.green;

???????????? ???gradebut.enabled = true;

??????????? }

??????? }

??? }

??? //顯示攻擊范圍

??? void ShowattRange()

??? {

??????? attRange.gameObject.SetActive(true);

??????? attRange.localScale = new Vector3(pagoda.attactRange * 2, 1, pagoda.attactRange * 2);

??????? attRange.position = pagoda.transform.position;

??? }

?

ShowPagodaInfo方法可以點(diǎn)擊防御塔時(shí)調(diào)用,并獲取該防御塔信息,而RefreshInfo方法除了在ShowPagodaInfo中調(diào)用外,等級(jí)增加時(shí)和金錢增加時(shí)也要刷新一次。

接下來就是怎樣點(diǎn)擊防御塔顯示信息了。實(shí)現(xiàn)原理是從攝像機(jī)位置發(fā)射射線,根據(jù)物體層檢測防御塔地形,如果該地形的子物體不會(huì)空,說明已經(jīng)安置防御塔,那就獲取該防御塔信息然后顯示。創(chuàng)建一個(gè)主控腳本PlayerController:

public class PlayerController : MonoBehaviour

{

??? public UpgradePanel upgradePanel;

Transform hitTerrain; //當(dāng)前地形

??? //顯示升級(jí)信息

??? public void ShowUpgradePanel()

??? {

??????? if (PagodaMenu.Instanc.readyToPlace == false)

??????? {

??????????? //點(diǎn)擊一定范圍除關(guān)閉

??????????? if (upgradePanel.gameObject.activeInHierarchy &&

??????????????? Vector3.Distance(upgradePanel.transform.position, Input.mousePosition) >= 300)

??????????????? CloseUpgradePanel();

?

???? ???????//從攝像機(jī)發(fā)射射線,檢測防御塔地形

??????????? Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

??????????? RaycastHit hit;

??????????? if (Physics.Raycast(ray, out hit, 500, LayerMask.GetMask("Pagoda")))

??????????? {

??????????????? //得到防御塔信息

???????? ???????Pagoda pagoda = hit.collider.GetComponentInChildren<Pagoda>();

??????????????? if (pagoda != null)

??????????????? {

??????????????????? hitTerrain = hit.collider.transform;

??????????????????? upgradePanel.ShowPagodaInfo(pagoda);

??????????????? }

??????????? }

??????? }

??????? else

??????????? upgradePanel.gameObject.SetActive(false);

??? }

??? //關(guān)閉升級(jí)信息和范圍顯示器

??? public void CloseUpgradePanel()

??? {

??????? upgradePanel.gameObject.SetActive(false);

??????? upgradePanel.attRange.gameObject.SetActive(false);

}

}

?

在Update中調(diào)用:


??? private void Update()

??? {

??????? if (Input.GetMouseButtonDown(0))

??????????? ShowUpgradePanel();

??????? //啟用后一直跟隨之前的剛才的地形,不受屏幕拖動(dòng)影響

??????? if (upgradePanel.gameObject.activeInHierarchy)

??????????? upgradePanel.transform.position = mainCamera.WorldToScreenPoint(hitTerrain.position + Vector3.up * 5);

??? }

?

在演示視頻中鏡頭的移動(dòng)與縮放也可以放入這個(gè)腳本中,該功能比較簡單,這里不啰嗦。

升級(jí)界面還有兩個(gè)按鈕,分別為出售和升級(jí),來到UpgradePanel腳本中創(chuàng)建相應(yīng)按鈕事件,掛到按鈕上:

//出售防御塔(按鈕事件)

public void PagodaSell()

{

??? pagoda.SellPagoda(); //調(diào)用防御塔初始方法

??? gameObject.SetActive(false);

??? attRange.gameObject.SetActive(false);

}

//升級(jí)防御塔(按鈕事件)

public void PagodaGrade()

{

??? pagoda.Upgrade(); //調(diào)用防御塔升級(jí)方法

??? RefreshInfo(); //刷新數(shù)據(jù)

??? //升級(jí)攻擊范圍

??? attRange.localScale = new Vector3(pagoda.attactRange * 2, 1, pagoda.attactRange * 2);

}

?

這些都完成后,我們的升級(jí)功能就可以正常運(yùn)行了。附上github:

https://github.com/wushupei/TowerDefenseGame


那么這個(gè)系列就此結(jié)束,有更多其他想法的讀者歡迎自由發(fā)揮,添加更多更有趣的功能。

有意向參與線下游戲開發(fā)學(xué)習(xí)的童鞋,歡迎訪問levelpp.com/

皮皮關(guān)的游戲開發(fā)QQ群也歡迎各位強(qiáng)勢插入:869551769

Unity快速上手系列之4:《塔防》終的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
博湖县| 崇文区| 隆化县| 华容县| 西乌珠穆沁旗| 句容市| 松阳县| 青岛市| 滦南县| 伊通| 莱阳市| 彭山县| 大方县| 黄梅县| 离岛区| 涪陵区| 公安县| 高邮市| 铜山县| 靖州| 阿克陶县| 常德市| 洞头县| 通海县| 故城县| 灌南县| 佛教| 泽普县| 达尔| 平塘县| 错那县| 九龙县| 濮阳县| 辉县市| 连城县| 武穴市| 金门县| 合江县| 定襄县| 兴仁县| 隆尧县|