斯坦福UE4C++課程P34-P38音頻動畫UI
首先是作業(yè)2的實現(xiàn)。
我們創(chuàng)建一個魔法球基類,供角色發(fā)射魔法球、黑洞、后面的AI發(fā)射魔法球繼承。
tip:包含BlueprintNativeEvent的UFUNCTION在cpp文件實現(xiàn)時要加_Implementation后綴。
改變較多,建議看作者github源碼,我在這里把之前做的作業(yè)2換成了作者的實現(xiàn),便于后邊的工作。

接下來我們創(chuàng)建聲音提示
新建一個Sound Cue文件MagicProjectile_Loop,其編輯界面類似于藍(lán)圖。
拖進(jìn)來wave player節(jié)點,選中一個音頻文件和looping表示循環(huán)播放。

我們發(fā)射魔法球后,如果距離離我們遠(yuǎn)了,該聲音應(yīng)該減小,可以直接在Sound Cue文件左側(cè)選擇Attenuation(衰減)欄的override來配置。
也可以單獨新建一個衰減Attenuation文件作為前者的配置。

我們開啟Enable Volume Attenuation(音量衰減)和Enable spatialization(空間化)
然后把在Sound Cue文件選中使用該衰減文件即可。
接下來新建一個Sound Cue文件,是魔法球撞擊音效,同樣使用前面的衰減文件。

我們還可以添加各種各樣的混合聲音節(jié)點,比如Doppler多普勒效應(yīng),靠近聲音源時,聲波頻率增大,音高變高,反之變低。

接下來進(jìn)入動畫藍(lán)圖
這里推薦看

tip:ctrl+P可以快速搜索資產(chǎn)
我們找到角色動畫藍(lán)圖Gideon_AnimBlueprint
動畫藍(lán)圖核心概念有圖表Graphs和動畫圖表Animation Graphs。圖表和藍(lán)圖類似,節(jié)點每幀調(diào)用,包含運行時角色運動的各種信息;動畫圖表決定了資產(chǎn)的姿勢。
在動畫藍(lán)圖中添加Blend Poses by bool:

接下來我們得看角色是否真的活著,我們不在動畫藍(lán)圖判斷,而是在別的地方直接賦值給IsAlive。
我們進(jìn)入角色AttributeComponent,新建
我們希望外部能夠調(diào)用該函數(shù),且在動畫藍(lán)圖中可以調(diào)用,所以在public下,設(shè)置為藍(lán)圖可調(diào)用。
函數(shù)體只需
因為該函數(shù)只是檢查Health,為了Health在函數(shù)體不被修改,我們設(shè)置該函數(shù)為const函數(shù),這意味著我們只能通過該函數(shù)讀取數(shù)據(jù)('Read-Only' Function)。
編譯后,回到動畫藍(lán)圖。
進(jìn)入事件圖表,從Try Get Pawn Owner拖出從類獲取組件節(jié)點,獲取到SAttributeComponet,調(diào)用IsAlive函數(shù),返回值賦值給動畫藍(lán)圖里的IsAlive變量。
現(xiàn)在的效果:

我們發(fā)現(xiàn),角色播放死亡動畫后,仍可以正常移動,因為我們沒有設(shè)置停止移動的機(jī)制。
在角色C++類添加函數(shù)
我們可以在構(gòu)造函數(shù)里調(diào)用該函數(shù),但使用PostInitializeComponents()是更好的選擇。
.h文件添加
.cpp文件添加
保證當(dāng)屬性組件的OnHealthChanged事件發(fā)生時都會調(diào)用角色類剛寫的OnHealthChanged函數(shù)。
現(xiàn)在角色死亡后,我們不能夠移動角色了。
后續(xù)可以做更多工作,比如死亡UI,調(diào)整攝像機(jī)等;可以在gamemode中對角色的死亡作出反應(yīng)。

接下來我們添加三維UI(傷害數(shù)字),當(dāng)我們擊中之前創(chuàng)建的不會動的敵人(Dummy)時會顯示傷害數(shù)字。
創(chuàng)建傷害數(shù)字UI:
project world to screen是把三維坐標(biāo)投影到二維屏幕坐標(biāo),除以視口比例是為了適配不同大小的UI(比如傷害數(shù)字UI的DPI是720P),使得UI顯示的位置統(tǒng)一。set render translation是把傷害數(shù)字平移到目標(biāo)位置渲染出來。構(gòu)造事件意思是傷害數(shù)字UI顯示2秒后刪除數(shù)字。

在Dummy敵人類藍(lán)圖中:
把self賦值給AttachTo,讓傷害數(shù)字顯示在敵人的位置。


最后是作業(yè)3
首先是第一部分

首先我們給魔法球添加飛行音效和擊中音效。
重寫父類的OnActorHit函數(shù),添加撞擊粒子系統(tǒng)和撞擊音效。
接下來把角色全身材質(zhì)替換為M_CharacterSimple,用之前做的材質(zhì)函數(shù)為該材質(zhì)添加閃光效果。
我們發(fā)現(xiàn)M_CharacterSimple有作者為我們留下的兩個節(jié)點,在材質(zhì)函數(shù)中添加好輸入節(jié)點后(作業(yè)要求Color和Speed能夠被我們修改),把該兩節(jié)點連接到自發(fā)光顏色Emissive Color。

在角色類中為TimeToHit分配值(和前面的Dummy敵人同理):
效果如下:

接下來我們在屬性組件AttributeComponent添加HealthMax:
在構(gòu)造函數(shù)中為其賦值為100。
替換生命值控件藍(lán)圖中的Health為HealthMax,并限制Health在0~HealthMax之間。

在屬性組件ApplyHealthChange函數(shù)下,Health+=Delta后添加:
實現(xiàn)限制。
現(xiàn)在角色死亡后血量不會繼續(xù)降低:

接下來我們添加傷害數(shù)字,使用Expose on Spawn來為數(shù)字賦值(之前我們做的Damage控件藍(lán)圖中的AttachTo變量勾選了Expose on Spawn,使得create widget節(jié)點顯示了AttachTo)。
我們在角色屬性類中添加變量DamageAmount(設(shè)置為public,便于在魔法球類中訪問該變量的值,來給角色添加傷害(之前我們直接用的-20.0f的傷害)),構(gòu)造函數(shù)中設(shè)置值為20。
魔法球類中添加傷害的語句變?yōu)椋?/p>
回到damage控件藍(lán)圖,為damage文本綁定函數(shù):

我們在角色類中單擊屬性組件,添加OnHealthChanged事件:

運行游戲,魔法球打中角色時的效果:

然后我們給傷害數(shù)字添加動畫,做得帶感一點。
damage控件藍(lán)圖左下角新建動畫,做好后在構(gòu)造事件后play animation。

現(xiàn)在的效果:

接下來我們做作業(yè)3的第二部分:Health Potion血瓶和發(fā)射魔法球前的粒子特效、相機(jī)震動

由于要求用Interact,所以我們模仿之前寶箱的做法。
HealthPotion.h
HealthPotion.cpp
效果如下:

接下來我們添加魔法球發(fā)出前的粒子系統(tǒng)和魔法球撞擊時的攝像機(jī)晃動。
在角色類的primaryAttack中,發(fā)出魔法球的前0.2秒,我們添加:
效果:

最后是添加魔法球撞擊相機(jī)震動
在魔法球類.h文件添加
cpp文件在OnActorHit函數(shù)添加相機(jī)震動
編譯后在魔法球藍(lán)圖選擇一個shake類(ExampleContent/CameraShake中有5個)
效果:
