2019-07-25 UE4《吃豆人-下》

《吃豆人》接上一篇。(其實是在等下載《火焰紋章-風(fēng)花雪月》順便來續(xù)寫)

七、走向勝利

統(tǒng)計豆子的數(shù)量,每吃一個就自減,減到0勝利。

打開PacmanGameModeBase.h ,聲明一個 int 類型的變量用來表示豆子數(shù)量,再聲明一個函數(shù),就叫 BeanWereEaten 吧...重寫父類的BeginPlay。

在BeginPlay中通過迭代器獲取豆子數(shù)量并統(tǒng)計,在?BeanWereEaten 中減少豆子數(shù)量,默認(rèn)每次-1。減到0玩家勝利。

豆子數(shù)量管理

在Bean類中聲明一個DestroyBean函數(shù),記得要加UFUNCTION() 。

豆子銷毀監(jiān)聽

然后在BeginPlay中綁定監(jiān)聽

綁定銷毀監(jiān)聽

最后實現(xiàn)DestroyBean函數(shù),獲取GameMode,調(diào)用BeanWereEaten方法。

實現(xiàn)銷毀監(jiān)聽

我們在豆子管理中加了log,當(dāng)豆子被吃時就會打印當(dāng)前的剩余數(shù)量。

打印當(dāng)前剩余豆子數(shù)量

超級豆,吃了會削弱敵人。

新建SuperBean類,繼承自Bean。本來想重寫DestroyBean,在里面添加削弱敵人的邏輯,但是編譯時被告知,不能重寫UFUNCTION修飾的函數(shù)。最后只好新建一個DestroySuperBean,然后重寫B(tài)ean的BeginPlay函數(shù),在調(diào)用Super::BeginPlay之后,再新增一個OnDestroyed的事件綁定,綁定到新建的DestroySuperBean。這樣SuperBean的OnDestroyed就被添加了兩次監(jiān)聽,據(jù)我觀察AddDynamic是會追加的,不是覆蓋,因此在新的DestroySuperBean中,只需要添加削弱敵人的調(diào)用就好了。

SuperBean的定義


SuperBean的實現(xiàn)

接下來去GameMode里添這個WeakenEnemy方法,添加后先寫個空方法,暫時只打印個log。待會再去實現(xiàn)。

創(chuàng)建基于SuperBean的藍(lán)圖,調(diào)整下尺寸和材質(zhì),以便和普通豆子區(qū)分,然后在四角刪除4個普通豆子,將超級豆拖進(jìn)場景,運(yùn)行發(fā)現(xiàn)超級豆被吃時,可以打印計數(shù),也可以觸發(fā)WeakEnemy。

那么,可以去實現(xiàn)WeakEnemy方法了。

打開PacmanGameModeBase類,聲明個敵人的結(jié)合,用來存儲所有敵人,這樣在WeakEnemy時方便獲取敵人的引用。


聲明敵人集合


初始化敵人集合,并實現(xiàn)削弱邏輯

在BeginPlay中收集敵人,在WeakenEnemy中遍歷敵人,調(diào)用敵人的Weaken函數(shù)。Weaken是 一個新增的函數(shù),需要在敵人類中去聲明并實現(xiàn)。

打開Enemy類,這里需要用到UE4的定時器,首先在Enemy類中聲明一個FTimerHandle。還要兩個函數(shù)用來削弱敵人、正?;瘮橙?。另外,再寫個枚舉記錄敵人的當(dāng)前狀態(tài)。

敵人聲明修改

在BeginPlay中設(shè)置默認(rèn)狀態(tài),設(shè)置敵人的最大移動速度,因為虛弱狀態(tài)會改變速度。

初始化敵人

然后去實現(xiàn)削弱和正常化函數(shù)。削弱時改變狀態(tài),更換材質(zhì),減少速度,然后在指定時間后調(diào)用恢復(fù)正常的方法。

削弱 和 還原

編譯播放,再吃到超級豆時,敵人就會被減速和變色,然后計時結(jié)束后又會恢復(fù)原樣。

八、玩家與敵人交互

現(xiàn)在玩家與敵人接觸時,只會相互阻擋,修改敵人和玩家的碰撞描述文件,修改Pacman與Enemy的碰撞響應(yīng)為overlap。最后在敵人類中添加碰撞監(jiān)聽。

接下來的一些內(nèi)容,都是基本的游戲邏輯,勝利、失敗、暫停、繼續(xù)也都是有限狀態(tài)機(jī)實現(xiàn)的,與虛幻4特性無關(guān),已經(jīng)消耗了太多時間在學(xué)習(xí)UE4上,項目那邊要補(bǔ)進(jìn)度了,因此不再一一記錄。

這里主要說一些遇到的問題。敵人的控制器忽然失靈了,看引擎的日志,發(fā)現(xiàn)有個警告 warnin?C4458 查了一下,說是自己聲明的變量名和父類中的變量名沖突了,改個名就好了。另外有時候項目連續(xù)崩潰,無法重啟虛幻4,需要在vs中重新生成解決方案。

還遇到個問題是,玩家與敵人碰撞時,會連續(xù)多次觸發(fā)overlap事件,這是因為,我在之前調(diào)試碰撞時,把玩家膠囊體、球體、網(wǎng)格的碰撞預(yù)設(shè)都改成了Pacman,其實只要設(shè)置一個膠囊體就可以了,其他還原。

還遇到一個巨坑的問題,google也沒找到解決辦法。

上面的設(shè)置雖然能使overlap觸發(fā)一次,但是當(dāng)?shù)厝俗詣踊丶視r,會被玩家擋住去路。于是,新增一個Empty碰撞通道和描述,所有碰撞響應(yīng)都設(shè)為忽略。將Pacman和Enemy加給各自的膠囊體,然后各自的其他組件都使用Empty,這樣在敵人回家時,不會被玩家擋住。

但是,問題就回來了

OnComponentBeginOverlap總是調(diào)用兩次,研究很久,發(fā)現(xiàn)如果碰撞后,不立即將玩家放置到出生點(diǎn),就不會overlap兩次。。于是將“玩家返回出生點(diǎn)”改成了異步方式。就好了。

九、UI和音效

新建HUD的子類,聲明一個字體UFont,重寫一個DrawHUD函數(shù),在藍(lán)圖中給字體賦值,在DrawHUD中繪制想要的內(nèi)容。我這里只寫了玩家生命值。

HUD


運(yùn)行效果

添加音效。

需要使用 wav 格式的音頻文件,將文件直接拖進(jìn)Content Browser下的目錄中就導(dǎo)入了。這里添加兩種,一個是用引擎添加的背景音樂,一個是用C++添加的敵人被攻擊音效。

背景音樂是自動播放且循環(huán)的,右鍵拖進(jìn)來的音頻文件->創(chuàng)建Cue 然后在SoundCue編輯面板的右側(cè)找到 looping 添加到節(jié)點(diǎn)中,放在WavePlayer和Output之間

SoundCue

然后在游戲場景中添加一個環(huán)境音效,把剛剛新建的SoundCue丟給環(huán)境音效,播放游戲就有了一個自動播放且循環(huán)的背景音樂了。

接下來是敵人音效,首先找到要使用的音頻文件,右鍵復(fù)制引用,接下來敵人類中聲明一個USoundWave,用ConstructHelpers去獲取剛剛復(fù)制的路徑來實例化USoundWave。在敵人被殺時調(diào)用UGameplayStatics::PlaySoundAtLocation來播放。

創(chuàng)建USoundWave


播放音效

到此,音效添加完成。

十、結(jié)束

我想以H5的方式啟動游戲時,又出現(xiàn)了一些錯誤,基本都是需要引入頭文件的問題。如果是.h文件,類名前加上class,如果是.cpp文件,需要include,可以去官網(wǎng)搜索用到的類,將網(wǎng)頁滑倒最后,找到類的路徑 引入即可。

查詢類的頭文件路徑

H5運(yùn)行效果,字體有點(diǎn)奇怪。

后續(xù)我還想在敵人的家里放一個只阻擋玩家,不阻擋敵人的“墻”,玩家的出生點(diǎn)也放一個只阻擋敵人的,這樣就都有基地了。還有場景的兩個出口,現(xiàn)在走過去就會掉進(jìn)深淵。。。想加個左右互傳的傳送陣。還有視角問題,想改成第一人稱視角的,再把球換成人形,做個小地圖。。。想想簡直就是曠野之息的迷宮了喂 ?(ˉ﹃ˉ?)。

放個項目工程文件

鏈接:https://pan.baidu.com/s/110aKqjRNIzwPG0d_raP-Ew

提取碼:e9hi

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容