UE4 C++ 實(shí)用技巧 (持續(xù)更新)
目錄
枚舉轉(zhuǎn)換?
UPARAM宏
碰撞通道轉(zhuǎn)換
__FUNCTION__
WorldContextObject
UserWidget中綁定 Axis
枚舉轉(zhuǎn)換
補(bǔ)充:
相比較 (int64)CardType? 此處用static_cast<int64>(CardType) 會(huì)更合適一些。
static_cast 能夠 讓int類型、枚舉類型兩者相互轉(zhuǎn)換,是非常實(shí)用且方便的技巧。
此外:枚舉從數(shù)字零開(kāi)始。
此外,枚舉可以使用泛型 - >??template <typename EnumType>。如:

UPARAM宏
(拆分: U + Param)
當(dāng)使用UFUNCTION宏,將C++ 里方法暴露至藍(lán)圖時(shí) ,被UPARAM(Ref) 標(biāo)記的引用類型參數(shù)將處于 ?左側(cè)引腳。
此外,常量引用(如?const FString& Name)位于 左側(cè)引腳。
此外,普通引用 (如 FVector & OutVector)位于右側(cè)引腳,這是非常、非常、非常常用的。除非是String三兄弟、以及一些體積較小的結(jié)構(gòu)體,其他情況下 原則上我們不應(yīng)該直接返回一個(gè)結(jié)構(gòu)體或數(shù)組,往往是通過(guò)這種 OutParam的形式獲得想要的數(shù)據(jù)。
演示代碼:
對(duì)于深受我們喜愛(ài)的結(jié)構(gòu)體?FGameplayAbilityTargetDataHandle,它的?Clear方法并未向藍(lán)圖暴露,因此需要我們?nèi)プ远x一個(gè)方法。
如圖:如果不使用 UPARAM(Ref) ,則參數(shù)位于右側(cè)引腳,無(wú)法使用。

而使用UPARAM(Ref) 后,參數(shù)對(duì)應(yīng)引腳轉(zhuǎn)移到左側(cè)

碰撞通道轉(zhuǎn)換
① 從數(shù)字七開(kāi)始
萌新對(duì)于ETraceTypeQuery 這個(gè)枚舉往往會(huì)手足無(wú)措,筆者當(dāng)初也為此困擾了許久,才得出
“自己添加的ObjectChannel對(duì)應(yīng)著的 ETraceTypeQuery?是從數(shù)字7開(kāi)始的”這個(gè)結(jié)論。


如圖,默認(rèn)的通道包括 WorldStatic、WorldDynamic、Pawn、PhysicsBody、Vehicle、Destructible 六個(gè),所以這里我自己新建的 Friend 通道是第七個(gè),即
在 C++代碼中,ETraceTypeQuery::TraceTypeQuery7 對(duì)應(yīng)著我這里自定義的Friend通道,8對(duì)應(yīng)著Enemy通道,以此類推。?

② CollisionChannel與 TraceTypeQuery
以GetHitResultUnderCursorByChannel為例,
當(dāng)在藍(lán)圖節(jié)點(diǎn)暴露時(shí),雖然它所顯示的TraceChannel參數(shù)為ETraceTypeQuery類型,但實(shí)際上是ECollisionChannel類,即默認(rèn)的 Visibility和Camera。

但是如果我們?cè)贑++中調(diào)用該方法,使用ECC_Visibility通道會(huì)報(bào)錯(cuò)。原因在于 編譯器無(wú)法將ECollisionChannel?自動(dòng)轉(zhuǎn)換成?ETraceTypeQuery。

這時(shí)使用通道轉(zhuǎn)換即可:

③ 使語(yǔ)義更加清晰
EObjectTypeQuery、ETraceTypeQuery、ECollisionChannel,它們都存在語(yǔ)義不清晰的毛病。顯然原因在于它是自上而下變更的。
★ 當(dāng)使用ECollisionChannel時(shí),我們往往需要到 config/DefaultEngine.ini中,手動(dòng)搜索

其實(shí)可以在項(xiàng)目名.h文件中 通過(guò)define關(guān)鍵字為其 指定全局別名,如
這樣使用起來(lái)會(huì)更方便一些。另外,官方在注釋中推薦一并修改?DefaultEngine.ini
其實(shí)沒(méi)太大必要
★ 同樣的,當(dāng)使用 TArray<TEnumAsByte<EObjectTypeQuery>>之類的參數(shù)時(shí),為了使語(yǔ)義清晰,最好的辦法是通過(guò)UPROPERTY向上暴露。如
藍(lán)圖中,它們會(huì)清楚地顯示成各自對(duì)應(yīng) 類型。

④?GetCollisionResponseToChannel
偶爾會(huì)用到的方法,組件級(jí)的,用來(lái)獲取某個(gè)組件對(duì)特定通道的響應(yīng),
如代碼所示,判斷 ThisComponent 對(duì) Interact通道的響應(yīng),是否為Overlap。
__FUNCTION__
非常實(shí)用的?預(yù)定義標(biāo)識(shí)符,用來(lái)表示 類名::方法名,用于LOG輸出。如:
推薦在輸入法中 自定義短語(yǔ) 添加一個(gè)log短語(yǔ),省得一遍又一遍打這玩意。如圖
win鍵 + 空格切換輸入法

至于圖中為什么將?ue 的四號(hào)位設(shè)置成?UE4 ,懂得都懂。
補(bǔ)充:
問(wèn):如何在C++中書(shū)寫(xiě)某些類?toString方法 以方便在某些情況下 輸出LOG?
答:參考 FVector的toString方法,使用?FString::Prinf 即可。// 個(gè)人習(xí)慣用toString而非ToString……
以某自定義的?SlotActor類為例:
?

WorldContextObject
在我們 繼承?UBlueprintFunctionLibrary?的類 ——?即自定義C++庫(kù)函數(shù)中,
如果我們想要獲取PlayerCharacter/PlayerController等對(duì)象,必然會(huì)用到 UGameplayStatics類,以?GetPlayerController的源代碼為例:
顯然,通過(guò)C++調(diào)用的話,必須要傳入?WorldContextObject才行。
一般地,如果是在其他類中,我們直接傳入 GetWorld() 就行了,
可如果是在 庫(kù)函數(shù)類中該如何傳參呢?
答案其實(shí)就在 GetPlayerController的代碼中,即只需 加上
meta = (WorldContext = "WorldContextObject")即可。
與雙引號(hào)內(nèi)文本相對(duì)應(yīng)的?參數(shù)對(duì)象 將會(huì)直接作為可以使用的?WorldContextObject對(duì)象,
并且該參數(shù)在藍(lán)圖調(diào)用的時(shí)候 將會(huì)自動(dòng)直接隱藏。
UserWidget中綁定 Axis
?UUserWidget 子類
頭文件中?
cpp 文件中
藍(lán)圖中顯示效果如下:

其中Axis參數(shù) 為ProjectSettings - Input 中所定義的 Axis Mapping 名稱