TomLooman_ActionRoguelike_AssignmentThree
該專欄用于保存對(duì)TomLooman的ActionRoguelike項(xiàng)目的學(xué)習(xí)筆記,學(xué)習(xí)過程中的思考與記錄不一定準(zhǔn)確。
教程參考:https://github.com/tomlooman/ActionRoguelike
基于UE5.0的項(xiàng)目實(shí)現(xiàn):https://github.com/CarolBaggins2023/TomLooman_ActionRoguelike_Tutorial

2023_08_07
Assignment 3(1):子彈飛行和爆炸音效,角色攻擊特效,最大血量屬性,傷害值UI,可交互血包,攝像頭震動(dòng)效果
?
先前我們制作了子彈飛行和爆炸的AudioCase,現(xiàn)在我們要使用它們。
我們?cè)谧訌椈愔袆?chuàng)建兩個(gè)聲音組件(UAudioComponent),并在編輯器中賦值。

其中子彈的飛行音效可以在子彈Spawn時(shí)就產(chǎn)生,所以我們想在子彈的BeginPlay中使用它,并且持續(xù)到子彈被銷毀。因?yàn)轱w行音效本身是循環(huán)的,所以我們可以用Activate激活聲音。

爆炸音效在爆炸時(shí)產(chǎn)生,所以我們?cè)贓xplode_Implementation中使用它,通過UGameplayStatics::PlaySoundAtLocation。其函數(shù)原型是static void PlaySoundAtLocation(const UObject* WorldContextObject, USoundBase* Sound, FVector Location, …),因?yàn)檫@里的參數(shù)要求是USoundBase類型,所以我們不能直接用UAudioComponent類型的成員變量,而是要獲取UAudioComponent類中的Sound成員變量,


?
要實(shí)現(xiàn)角色攻擊時(shí)的特效,我們先在SCharacter類中創(chuàng)建UParticleSystem類的成員變量。
之前在子彈類中我們也創(chuàng)建了粒子效果的成員變量,子彈的飛行效果成員變量是UParticleSystemComponent類,子彈的爆炸效果成員變量是UParticleSystem類。兩個(gè)類的區(qū)別是粒子效果模板(UParticleSystem)用于定義粒子效果的屬性和行為(是一種規(guī)則),而粒子效果組件(UParticleSystemComponent)用于實(shí)例化、渲染和控制粒子效果的運(yùn)行時(shí)行為;或者目前的情況時(shí),持續(xù)一段時(shí)間的、動(dòng)態(tài)的、有位移的用UParticleSystemComponent,靜態(tài)的、一瞬間的用UParticleSystem。

我們?cè)诠艉瘮?shù)中通過UGameplayStatics::SpawnEmitterAttached使用這個(gè)粒子效果,其函數(shù)原型為UParticleSystemComponent* UGameplayStatics::SpawnEmitterAttached(UParticleSystem* EmitterTemplate, USceneComponent* AttachToComponent, FName AttachPointName),我們將粒子效果附著到角色的網(wǎng)格組件上,并附著到手部位置。

?
?
我們可以通過修改角色的Mesh組件使用材料來為角色添加類似受擊發(fā)光的效果。

將原本連接到發(fā)光度的節(jié)點(diǎn)替換為我們的材料函數(shù)。

這個(gè)材料函數(shù)上半分支和之前受擊發(fā)光物體的材料函數(shù)類似,區(qū)別在于加了一條表示顏色的分支。因?yàn)榘咨腞GB是(1, 1, 1),所以表示顏色的三維向量乘以一個(gè)常數(shù)可以表示不同顏色發(fā)光度。

我們將閃光速度轉(zhuǎn)換為變量,在創(chuàng)建材料的實(shí)例后,就可以方便地在實(shí)例中調(diào)整閃光速度。將該材料實(shí)例應(yīng)用到角色Mesh組件的Material后,就可以實(shí)現(xiàn)角色受擊閃光的效果。

?
我們之前顯示血量時(shí)使用的是類的默認(rèn)值,但我們可以通過給角色創(chuàng)建一個(gè)最大血量的屬性來替代。
我們?cè)赨SAttributeComponent類中創(chuàng)建了一個(gè)最大血量的成員變量,并在構(gòu)造函數(shù)中賦初值。

這樣在血條UI的藍(lán)圖中,我們就可以直接使用新的血量和最大血量計(jì)算百分比,從而給血條材料中的參數(shù)賦值,改變血條不同顏色的占比。

也可以修改屬性組件類中的ApplyHealth成員函數(shù)的實(shí)現(xiàn),

?
我們之前制作了一個(gè)UI,這個(gè)UI將一個(gè)對(duì)象作為參數(shù),在對(duì)象受擊時(shí)創(chuàng)建該UI并傳入自身,從而將對(duì)象的位置作為UI出現(xiàn)的位置。但我們并沒有實(shí)現(xiàn)出現(xiàn)的UI就是受擊傷害的效果。
我們所要做的就是用給UI中的Text變量賦值(將組件作為變量)。這里的邏輯是,(1)每當(dāng)子彈與物體發(fā)生overlap后,就調(diào)用該物體的屬性組件成員變量的ApplyHealthChange成員函數(shù),ApplyHealthChange成員函數(shù)一邊修改Health屬性值(屬性組件類中的float成員變量),一邊將OnHealthChanged委托進(jìn)行廣播(屬性組件類中的委托成員變量);(2)該物體的屬性組件成員變量的OnHealthChanged委托在構(gòu)造函數(shù)中已經(jīng)與該物體的一些成員函數(shù)(這里是OnHealthChanged,與委托名相同,不要搞混)綁定,因此這些成員函數(shù)一直在監(jiān)聽委托是否觸發(fā),一旦觸發(fā)就執(zhí)行函數(shù)。
因此,要實(shí)現(xiàn)物體受擊后,改變UI中的Text變量,可以給該委托多綁定一個(gè)函數(shù),在這個(gè)函數(shù)中創(chuàng)建UI,然后將委托中的Delta參數(shù)傳遞給UI的Text變量(委托聲明時(shí)有一個(gè)Delta參數(shù)表示傷害值,在ApplyHealthChange中也被使用)。我們通過藍(lán)圖完成,先將Delta賦值給一個(gè)float類型的變量,再在UI中把該float類型的變量賦給Text。


我們還可以給Text添加UI動(dòng)畫,和之前血槽旁邊數(shù)字的動(dòng)畫類似,新增Animation,為Text新增Track,在時(shí)間軸上添加不同的Text,然后進(jìn)行自動(dòng)的插值。

動(dòng)畫完成后可以在藍(lán)圖中調(diào)用,放置在創(chuàng)建UI之后,

?
?
2023_08_07
Assignment 3(2):醫(yī)療包,攻擊時(shí)相機(jī)震動(dòng)效果
?
我們可以直接制作一個(gè)醫(yī)療包的C++類,繼承之前創(chuàng)建的ISGameplayInterface接口類,類似于寶箱的實(shí)現(xiàn)方法。但是可以想到之后還會(huì)有很多類似的需要交互的物品,所以我們可以制作一個(gè)交互物品基類。
?
交互物品基類繼承AActor和ISGameplayInterface,有一個(gè)碰撞組件,實(shí)現(xiàn)ISGameplayInterface中的純虛函數(shù)(但實(shí)際上實(shí)現(xiàn)為空,因?yàn)槊總€(gè)交互物品實(shí)現(xiàn)的效果不同,所以在基類中不做任何操作)。



?
我們對(duì)交互物品的交互邏輯是這樣的,我們與物品交互后,物品應(yīng)不可見且無碰撞(進(jìn)入失效狀態(tài)),在一段時(shí)間后再回復(fù)可見和碰撞(恢復(fù)有效狀態(tài))。因此,我們創(chuàng)建了Set函數(shù)直接控制對(duì)象的可見性和碰撞,Show和Hide函數(shù)調(diào)用Set函數(shù),并在Hide函數(shù)中通過時(shí)間句柄調(diào)用Show函數(shù)。

它們的實(shí)現(xiàn)如下。其中,Set函數(shù)中SetVisibility
的函數(shù)原型為void SetVisibility(bool bNewVisibility, bool bPropagateToChildren=false),所以它不僅控制父類成員的可見性,還能控制子類成員的可見性。

?
交互物品基類創(chuàng)建好后,我們的醫(yī)療包類就可以繼承交互物品類。

我們?cè)卺t(yī)療包類中要真正地實(shí)現(xiàn)Interact函數(shù),同時(shí)因?yàn)獒t(yī)療包類自身要實(shí)現(xiàn)的功能,我們?cè)黾恿酥委熈砍蓡T變量。

在交互的實(shí)現(xiàn)中,我們非常自然地先判斷觸發(fā)交互的Actor是否有效,獲取該Actor中的屬性組件成員變量,并判斷其有效性。這里增加了兩個(gè)有些重復(fù)邏輯,第一個(gè)是如果Actor的血量是滿的,就不能撿血包。第二個(gè)是判斷交互后角色血量的實(shí)際變化,如果實(shí)際變量非零,則確實(shí)發(fā)生了交互,那么就調(diào)用Hide函數(shù),血包進(jìn)入失效狀態(tài)。


?
教程提供了一些CameraShake的資產(chǎn),我們可以嘗試使用它們。當(dāng)子彈擊中目標(biāo)時(shí),我們讓玩家的鏡頭發(fā)生抖動(dòng)。
我們?cè)谧訌椈愔刑砑覥ameraShakeBase子類的成員變量,并允許在編輯器中進(jìn)行賦值。


我們?cè)贓xplode中調(diào)用它。這里我們只考慮一個(gè)玩家的情況,所以使用GetWorld()->GetFirstPlayerController()獲得第一個(gè)玩家的控制器,并在上面調(diào)用CameraShake,
