虛幻引擎中的日誌系統
在軟體專案中,日誌一直扮演著一個及其重要的角色。程式設計師經常依賴它來定位問題,在某些不方便除錯的情況下,日誌甚至是唯一一個可以依賴的工具。虛幻作為一個遊戲引擎,它的強大體現在各個方面,也包括日誌系統。在本文裡我就引擎提供的三種打日誌的方式來介紹這一系統。
提到日誌,大概我們第一個想到的就是在輸出終端上列印的日誌。對於這類日誌引擎提供了UE_LOG巨集來實現。UE_LOG不僅僅有了種類眾多的預定義(Category)種類,還有日誌級別(Verbosity)控制。預定義的日誌種類宣告可以檢視CoreGlobal.h檔案。我們選擇LogTemp這個預定義的日誌種類來舉例,比如如下的程式碼:
UE_LOG (LogTemp, Log, TEXT("Hit, hit"));
UE_LOG(LogTemp, Warning, TEXT("Hit, hit"));
UE_LOG(LogTemp, Error, TEXT("Hit, hit"));
這段程式執行起來後會在引擎編輯器裡的Output Log視窗輸出這樣的日誌: UE_LOG巨集的第一個引數就是日誌種類(Category),第二個是日誌級別(Verbosity),剩下的就是日誌內容了。我們可以看到編輯器根據日誌級別的不同,特意用不同的顏色列印日誌,以方便我們檢視。當日志數量過多時,我們還可以根據種類(Category)對日誌進行過濾,只檢視我們感興趣的類別。
除了使用引擎預定義的日誌種類輸出,我們還可以自定義日誌種類(Category)。比如我們的模組叫FPSGame,我們可以在模組標頭檔案上加上一個宣告日誌種類的巨集:
DECLARE_LOG_CATEGORY_EXTERN(FPSGame, All, All)
然後在模組的CPP檔案中加上定義日誌種類的巨集:
DEFINE_LOG_CATEGORY(FPSGame)
這樣我們就可以用FPSGame這個日誌類別來輸出日誌:
UE_LOG(FPSGame, Warning, TEXT("Hit, hit"))
用UE_LOG輸出日誌只會在編輯器的Output Log窗口裡顯示,但我們並不只是在編輯器裡執行我們的遊戲,引擎的開發者為我們也想到了這一點,給我們提供了一個在遊戲螢幕上顯示日誌的函式:AddOnScreenDebugMessage。比如在程式碼裡我需要在玩家往前/右移動時在螢幕上顯示移動的數值,像下面這樣做:
void AFPSCharacter::MoveForward(float Value)
{
FString DebugMsg = FString::Printf(TEXT("Move forward:%s"), *FString::SanitizeFloat(Value));
int32 key = 1;
GEngine->AddOnScreenDebugMessage(key, 1, FColor::Green, DebugMsg);;
}
void AFPSCharacter::MoveRight(float Value)
{
FString DebugMsg = FString::Printf(TEXT("Move right:%s"), *FString::SanitizeFloat(Value));
int32 key = 2;
GEngine->AddOnScreenDebugMessage(key, 1, FColor::Blue, DebugMsg);
}
當程式執行起來後,你就可以在遊戲視窗左上角看到這樣的顯示: 需要提一下的是AddOnScreenDebugMessage的第一個引數是key值,用來控制螢幕上顯示日誌的唯一性的,也就是說key值相同的日誌只會顯示一個。另外就是在引擎版本4.19裡這個函式有bug會導致日誌在螢幕上顯示不出來,假如你遇到這樣的問題,升級到最新版本應該就好了。
除了在螢幕上顯示日誌,有時候我們還需要在遊戲3D場景裡也顯示日誌,比如我們在射擊遊戲裡標註一下子彈飛行過程中碰撞到了那些位置,為了滿足這樣的需求,引擎特意提供了DrawDebugString這個函式,使用方式如下:
void AFPSProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL) && OtherComp->IsSimulatingPhysics())
{
OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
Destroy();
}
DrawDebugString(GetWorld(), Hit.ImpactPoint, "Hit", nullptr, FColor::Red, 2.0f, true);
}
這段程式執行起來後就會在子彈碰撞的地方都標上紅色的“Hit”字樣,幫助開發者定位子彈的運動軌跡:
以上就是虛幻引擎提供的日誌功能了。有了這三種打日誌的方式,作為使用者的我們要是使用得當,一定能讓我們的開發事半功倍。