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

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

你的生命是人類的貨幣——用Unity實現(xiàn)《Seed》(三)

2019-11-13 18:40 作者:皮皮關(guān)做游戲  | 我要投稿

作者:Yumir


哈嘍大家好我是Yumir。

不出意外這是本系列的最后一篇文章啦,感興趣的同學(xué)可以從頭開始看哦。傳送門如下:

本次使用了狀態(tài)模式實現(xiàn)了簡單的AI,代碼也比較多說的比較細(xì),有條件的同學(xué)可以試著自己實現(xiàn)一發(fā)。

傳送門:你的生命是人類的貨幣——用Unity實現(xiàn)《Seed》(一)
? ? ? ? ? ? ??你的生命是人類的貨幣——用Unity實現(xiàn)《Seed》(二)

我們今天的目標(biāo)是完成人類部分的功能,因為人類這邊邏輯上都是一樣的(只有貼圖差別),所以只實現(xiàn)一個類型的人類。

作者在LD上面的配圖


我們需要實現(xiàn)的功能有:

1、人類出生之后會尋找樹并砍樹。

2、將樹砍倒后,要有一個人把樹送回人類的房子,其他人繼續(xù)砍樹。

3、將木材送到人類的房子,增加貨幣購買新的人類。

4、人會變老(順便實現(xiàn)被植物攻擊的方法)。

----------------------------開始準(zhǔn)備預(yù)制體----------------------------------

首先我們來實現(xiàn)人類的預(yù)制體,每個類型的人類都是四個動畫,動畫的制作方法之前已經(jīng)講過:

用Unity做一個萌萌噠游戲(附資源)

人類的四個動畫

動畫的狀態(tài)機如圖所示,再在人類身上添加一個控制人類行為的腳本,一個人類的預(yù)制體就制作完成啦,比樹的預(yù)制體簡單很多很多。

人的狀態(tài)機

----------------------------預(yù)制體準(zhǔn)備完畢----------------------------------

接下來是人的AI行為,對需求進(jìn)行分析,首先我們需要實現(xiàn)一個讓人類移向目標(biāo)的方法,熟悉unity的同學(xué)此時就很開心了,這多簡單啊,求出一個指向目標(biāo)點的向量,讓物體向著這個方向移動就可以了。確實如此,再復(fù)雜的建筑也是用建材和粘合劑組合起來的。

人物的移動方法很簡單,但是還沒到分享代碼的時候,還記得文章開頭我說了會用到狀態(tài)模式么?

在看看我們的需求,人類有:找樹、砍樹、回家交貨、死亡,這四個狀態(tài),實際上還有一個狀態(tài)是原游戲的“原始人”特有的(原游戲的原始人沒有工具可以砍樹),也可以用于場景內(nèi)沒有樹的時候,人類會隨機走動。

當(dāng)人類找樹的時候,人類需要以樹為目標(biāo)尋路;

當(dāng)人類在砍樹的時候,人類不需要尋路;

當(dāng)人類回家交貨的時候,人類需要以“家”為目標(biāo)尋路;

當(dāng)人類死亡的時候,人類不會移動;

也就是說我們可以根據(jù)當(dāng)前人類的狀態(tài)設(shè)置目標(biāo)點。


switch?(humanState){

????case?HumanState.GoNone:

??????target.position?=?new?Vector3(Random.Range(0,?100),?Random.Range(0,?100),?Random.Range(0,?100));

??????break;

????case?HumanState.GoHome:

???????target?=?GameManager.instance.humanHome.transform;

???????break;

????case?HumanState.GoTree:

????????target?=?GameManager.instance.GetHumanTargetTree(transform);

????????break;

????case?HumanState.Attack:

????????break;

????case?HumanState.Die:

?????????target?=?transform;

?????????break;}

?

那么場景中的樹那么多,人類怎么知道自己要跑向哪顆樹呢?

人跑向樹

如果你剛剛認(rèn)真看了上面的代碼就會發(fā)現(xiàn)我寫了一個方法,在“GoTree”狀態(tài)下調(diào)用。

我在GameManager中聲明了一個樹的list,當(dāng)樹長出來的時候就會把自己加到這個list里面,當(dāng)樹的生命值小于等于零時將自己從該list刪除并播放樹死亡的動畫,這個list就是下面的“TreeGOList”。這個方法返回了一顆離當(dāng)前人類最近的樹作為人類的目標(biāo)。

public Transform GetHumanTargetTree(Transform humanTransform)

{

????????Transform targetTrans = humanTransform;

????????float direction = 2000;

????????foreach (GameObject item in TreeGOList)

????????{

????????????if (Vector3.Distance(item.transform.position, humanTransform.position) < direction)

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

????????????????direction = Vector3.Distance(item.transform.position, humanTransform.position);

????????????????targetTrans = item.transform;

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

????????}

????????return targetTrans;

}

?

現(xiàn)在人類有了自己的目標(biāo),我們來想象一下:

游戲開始,人類出現(xiàn)開始找樹,他跑到樹的面前了,我們看到了,可是“人類”并不知道,他還在不停的尋路。

所以我們讓他在距離目標(biāo)點還有一段距離的時候停下來,進(jìn)入砍樹狀態(tài),但是目標(biāo)點也不一定就是樹啊,所以我們還要判斷嘛!當(dāng)人類往回走的時候需要轉(zhuǎn)身,總不能退著回家嘛!所以我們需要通過比較目標(biāo)點和人類自身的x軸大小改變?nèi)祟惖摹癴lipX”的值。

人類可真是麻煩,但是沒關(guān)系,這個麻煩我?guī)湍銈兏愣?,來看代碼。

curenPosition = this.transform.position;

moveDirection = target.position - curenPosition;

moveDirection.Normalize();

if (curenPosition.x > target.position.x)

{

????GetComponent<SpriteRenderer>().flipX = true;

}

else if (curenPosition.x < target.position.x)

{

????GetComponent<SpriteRenderer>().flipX = false;

}

if (Mathf.Abs(curenPosition.x - target.position.x) < 35f&& Mathf.Abs(curenPosition.y - target.position.y) < 15)

{

?????transform.position = new Vector3(transform.position.x, transform.position.y, target.position.z);

?????if (target.tag == "Tree" && humanState == HumanState.GoTree)

?????{

?????????humanState = HumanState.Attack;

?????????animator.SetBool("attack", true);

?????????target.GetComponent<Tree>().AddAttacker(gameObject);

??????}

??????else if (target.tag == "Home" && humanState == HumanState.GoHome)

??????{

??????????//把身上攜帶的木材交給管理器,然后把自身攜帶的木材清零

??????????GameManager.instance.AddWood(wood);

??????????wood = 0;

??????????animator.SetBool("gohome", false);

??????????humanState = HumanState.GoTree;

???????}

}

else

{

??????transform.Translate(moveDirection * speed * Time.deltaTime);

}

?

人類找到了目標(biāo)之后還有什么操作呢,一個是砍樹,另一個就是交貨啦。

先說砍樹,在上一篇文章里我們在樹的腳本中寫了被攻擊方法,那么我們要怎么獲取到他呢?

欸!你已經(jīng)在上面的代碼看到了!對的,我們已經(jīng)知道目標(biāo)是哪個樹了,直接Get他!但是不是上面那句代碼哦,是這段:


private void Attack()

{

???target.GetComponent<Tree>().BeAttack(attack);

???//音效

}

?

這句代碼在哪里調(diào)用呢?答案是在幀事件調(diào)用噠!在人類的刀砍中樹的那一幀加入幀事件,調(diào)用這個方法就可以啦~

那么之前提到的代碼,為什么要在尋路碰到樹的時候調(diào)用呢,這就要說到我們的第二個目標(biāo):將樹砍倒后,要有一個人把樹送回人類的房子,其他人繼續(xù)砍樹。

只有一個人可以獲得遺產(chǎn)

也就是我們需要讓人知道自己的目標(biāo)樹已經(jīng)去世這個消息,而且只有一個人可以獲得這棵樹的遺產(chǎn),我們要怎么做到呢。

其實砍樹的人群就是若干的“觀察者”,而被砍的樹就是“通知者”,這棵樹在完全去世之前還要先向每個人類都說一句“嘿,我被你打敗了啦,快去砍別的樹吧”并且把自己的遺產(chǎn)交給其中一個人類,讓他回家。

說得花里胡哨的,其實就是在每棵樹的身上也有一個list,這個list是用來存儲當(dāng)前砍伐自己的人類的,在人類的腳本上寫了人類的狀態(tài)轉(zhuǎn)換方法,當(dāng)樹死亡時通過foreach遍歷調(diào)用就行了。人類開始砍樹時加入該list,死亡時將自己從該list上刪除。

if (attacker.Count != 0)

{

????foreach (GameObject item in attacker)

????{

????????item.GetComponent<Human>().GoTree();

????}

????????attacker[0].GetComponent<Human>().GoHome(wood);

}

?

再來是回家交貨,樹通知了砍樹的人并且將自己的遺產(chǎn)交給了其中一個人類,這個樹的“wood”就賦值到了人類的“wood”,當(dāng)人類到達(dá)根據(jù)地的時候就會將這個“wood”傳遞給管理器,這段代碼在前面已經(jīng)出現(xiàn)過了,那么問題是管理器中發(fā)生了什么。

新的人類誕生

游戲中的木材是“人類世界”的貨幣,可以用來購買新的人類,新的人類又會去砍樹,反復(fù)循環(huán)。但是如果是交貨的同時購買新的人類的話游戲會仿佛沒有獲得過貨幣,所以這里我用了一個延時將購買新的人類的操作延時觸發(fā)。

? ? public void AddWood(int num)

????{

????????wood += num;

????????woodText.text = wood.ToString();

????????Invoke("BuyHuman", 0.5f);

????}

?

每次購買的人類數(shù)量是所有貨幣的數(shù)量除以當(dāng)前人類的價格的商(不同時代的人類價格可以改變),為了人類生成的時候不是堆在一起的,給他的坐標(biāo)加上一個隨機數(shù)。

public void BuyHuman()

????{

????????if (wood / humanPrice != 0)

????????{

????????????int num = wood / humanPrice;

????????????for (int i = 0; i < num; i++)

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

????????????????Instantiate(humanPrefab, new Vector3(humanHome.transform.position.x + Random.Range(20, 60), humanHome.transform.position.y + Random.Range(20, 60), humanHome.transform.position.z), Quaternion.identity);

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

????????????wood = wood % humanPrice;

????????????woodText.text = wood.ToString();

????????}

????}

?

這樣一來我們的前三個目標(biāo)都已經(jīng)完成了,剩下最后一個目標(biāo):人類會死亡。

人類の死亡

這是一個很簡單的操作,回憶一下上一篇文章,有一種植物會讓人類加速死亡,我們可以一起做了,我是這樣實現(xiàn)的——增加一個老化速度,每次被大王花攻擊的時候增加這個速度,這個速度的初始值為1。

private void HumanOld()

????{

????????if (life > 0)

????????{

????????????life -= Time.deltaTime*oldVelocity;

????????}

????????else if(humanState != HumanState.Die)

????????{

????????????animator.SetTrigger("die");

????????????humanState = HumanState.Die;

????????????if(humanState == HumanState.Attack)

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

????????????????target.GetComponent<Tree>().RemoveAttacker(gameObject);

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

????????}

????}

?

最后一個功能是對應(yīng)了我上一篇做的植物預(yù)制體中的歌唱家,他的能力是概率使人類迷惑,也就是暫停人類的行動。這個功能可以通過“animator.speed”來實現(xiàn),我用協(xié)程來控制這個迷惑的時間,并且改變了貼圖的顏色,使效果更明顯。

以上就是該游戲所有的功能實現(xiàn)啦,有了這些功能已經(jīng)足夠同學(xué)自主補充完整個游戲了,當(dāng)然我們也不一定要完全把原來的游戲完完整整的做出來,學(xué)習(xí)嘛,學(xué)習(xí)的事情,也是要勞逸結(jié)合的。

——分割線——

歡迎加入游戲開發(fā)群歡樂攪基:869551769

有意向參與線下游戲開發(fā)學(xué)習(xí)的讀者可戳這里進(jìn)一步了解:levelpp.com/


你的生命是人類的貨幣——用Unity實現(xiàn)《Seed》(三)的評論 (共 條)

分享到微博請遵守國家法律
凤阳县| 鲜城| 阳西县| 南漳县| 平塘县| 扶绥县| 泸西县| 白河县| 荔浦县| 万源市| 河南省| 日照市| 无棣县| 桂东县| 简阳市| 长汀县| 军事| 新安县| 徐汇区| 洛川县| 瑞昌市| 太保市| 宁津县| 资中县| 盘锦市| 永福县| 潮安县| 宜春市| 古蔺县| 永年县| 泉州市| 东安县| 鸡东县| 莱芜市| 如皋市| 来宾市| 奉新县| 南阳市| 镇沅| 锡林郭勒盟| 曲沃县|