虚幻引擎中的日志系统

在软件项目中,日志一直扮演着一个及其重要的角色。程序员经常依赖它来定位问题,在某些不方便调试的情况下,日志甚至是唯一一个可以依赖的工具。虚幻作为一个游戏引擎,它的强大体现在各个方面,也包括日志系统。在本文里我就引擎提供的三种打日志的方式来介绍这一系统。

提到日志,大概我们第一个想到的就是在输出终端上打印的日志。对于这类日志引擎提供了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窗口输出这样的日志:


OutputLog.png

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);
 }

当程序运行起来后,你就可以在游戏窗口左上角看到这样的显示:


ScreenString.PNG

需要提一下的是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”字样,帮助开发者定位子弹的运动轨迹:


StringInScene.PNG

以上就是虚幻引擎提供的日志功能了。有了这三种打日志的方式,作为使用者的我们要是使用得当,一定能让我们的开发事半功倍。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,019评论 3 119
  • 上肢 项目一:引体向上 -40 12*2, -35 12*2 项目二:高位下拉 25kg 12*4 项目三:哑铃卧...
    oppy阅读 150评论 0 0
  • 毒品是没有希望人的希望。----吉姆·莫里森 第一章 地球新历 2535年6月35日 东8区时间 20:25 来自...
    零重力科幻阅读 745评论 2 3
  • 坦白说,这期2阶班是教得比较辛苦的一个班,除了原有1阶升上来的孩子,又插班加入两个新同学。他们很活跃,英语...
    TinaLiu丹阅读 289评论 0 0
  • 人要想得开,放得下。今天再大的事,明天就是小事;今年再大的事,明年就是故事;今生再大的事,来世就是传说。 ...
    来喜wzf阅读 1,429评论 28 43