虚幻引擎(UE4) 日志、打印运行时信息

概述

日志用于引擎及时反馈给我们运行时刻数据和信息。强大的用途不限于如下:

  •   函数是否被调用
  •   算法使用的什么数据
  •   上报错误给开发组或者用户
  •   特定时刻强制运行致命错误(如断言错误)以停止执行程序。

本章将介绍如何在虚幻引擎中输出日志。

目录

获取日志

使用方法

日志详情级别

设置自己的日志类别

使用样例

格式化打印

打印字体的颜色

快速打印提示

其他打印方式

日志关键字

有用的控制台命令

日志命令行

环境变量

配置文件

 

获取日志

  • 游戏中
    为了在游戏中能看到日志,你必须以“-Log”的方式运行游戏(创建一个编辑器快捷方式的可执行程序,并在后面加上 “-Log”),或者在游戏中控制台输入命令行"showlog"

  • 在编辑器中
    日志信息被打印在“Output”窗口,Output窗口打开方式:Window -> Developer -> Output Log。

    如果你使用编辑器和PIE,日志默认是可用的,因为在你的引擎 ini 文件里已经声明了 "GameCommandLine=-log"
    如果还是看不到日志,请按上面的方式操作添加“-Log”命令行。
     

使用方法

UE_LOG(LogTemp, Warning, TEXT("my message"));

这种方式打印不需要指定自定义的日志类别,尽管这样做会让日志清晰和整齐。

日志详情级别

       日志类别被用于控制那些被打印的内容,帮你更加清晰识别日志的重要等级。每个日志按照自己的级别来分类显示,开发者可以迅速查找到对应的日志内容。这些类别包括:编译时详情级别、默认的详情级别、ini详情级别和运行时详情级别:

  • Fatal(致命错误)
    打印到控制台并写入日志文件,即使日志不可用/不打印也会导致崩溃。

  • Error
    打印到控制台并写入日志文件,在日志文件中默认显示为红色

  • Warning
    打印到控制台并写入日志文件,在日志文件中默认显示为黄色

  • Log
    只打印写入日志文件中,不会打印到控制台。在编辑器的Output窗口也能看到。

  • Verbose
    只打印写入日志文件中,不会打印到控制台。通常用来查看更详细的日志信息和调试

  • VeryVerbose
    只打印写入日志文件中,不会打印到控制台。通常用来查看非常详细的日志记录,也会产生垃圾信息输出。

 

设置自己的日志类别

日志类别宏

      分别在游戏头文件(YourGame.h)中声明DECLARE_LOG_CATEGORY_EXTERN,在源文件(YourGame.cpp)中定义 DEFINE_LOG_CATEGORY。

声明日志类别宏有三个参数,每个声明的日志类别都应该在.cpp文件中有一个定义。

DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity);
  • 参数CategoryName 是你定义的类别名。
  • 参数DefaultVerbosity 如果在INI文件没有指定详情级别,这种类别下的日志都会被记录。
  • 参数CompileTimeVerbosity 是要在代码中编辑的最大详情类别

只需要一个类别名字就能定义日志宏:

DEFINE_LOG_CATEGORY(CategoryName);

 

使用样例

         你可以根据你的喜好来定义不用的日志类别

          下面是一个有用的例子。

          你可能在某个游戏系统中经常遇到问题,在调试中可能你想要更详细的日志,但是程序结束调试后,你又想要刚刚的日志记录,发现日志文件中有很多垃圾信息,你改怎么做?那就使用不用的日志类别。

 Game.h

//普通日志
DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);

//游戏启动日志
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameInit, Log, All);

//AI日志
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameAI, Log, All);

//其他系统日志
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameSomeSystem, Log, All);

//错误日志,通常可以通过日志定位到错误的位置
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameCriticalErrors, Log, All);

Game.cpp 

#include "MyGame.h"

//普通日志
DEFINE_LOG_CATEGORY(LogMyGame);

//游戏启动日志
DEFINE_LOG_CATEGORY(LogMyGameInit);

//AI日志
DEFINE_LOG_CATEGORY(LogMyGameAI);

//其他系统日志
DEFINE_LOG_CATEGORY(LogMyGameSomeSystem);

//错误日志。通常可以通过日志定位到错误的位置
DEFINE_LOG_CATEGORY(LogMyGameCriticalErrors);

下面是调用打印

//...
void UMyClass::FireWeapon()
{
	UE_LOG(LogMyGameSomeSystem, Verbose, TEXT("UMyClass %s entering FireWeapon()"), *GetNameSafe(this));
	//逻辑
	UE_LOG(LogMyGameSomeSystem, Verbose, TEXT("UMyClass %s Attempting to fire."), *GetNameSafe(this));
	if (CheckSomething())
	{
		UE_LOG(LogMyGameSomeSystem, Log, TEXT("UMyClass %s is firing their weapon with charge of %f"), *GetNameSafe(this), GetCharge());
	}
	else
	{
		UE_LOG(LogMyGameSomeSystem, Error, TEXT("UMyClass %s CheckSomething() returned false during FireWeapon(), this is bad!"), *GetNameSafe(this));
	}
	//其他打印
	UE_LOG(LogMyGameSomeSystem, Verbose, TEXT("UMyClass %s leaving FireWeapon()"), *GetNameSafe(this));
}

void UMyClass::Tick(float DeltaTime)
{
	UE_LOG(LogMyGameSomeSystem, VeryVerbose, TEXT("UMyClass %s's charge is %f"), *GetNameSafe(this), GetCharge());
	if (something)
	{
		UE_LOG(LogMyGameSomeSystem, VeryVerbose, TEXT("Idk"));
	}
	if (somethingelse)
	{
		UE_LOG(LogMyGameSomeSystem, VeryVerbose, TEXT("Stuff"));
	}
}
//...

 

格式化打印

 打印一个 Message

UE_LOG(YourLog,Warning,TEXT("This is a message to yourself during runtime!"));

 打印一个String

UE_LOG(YourLog,Warning,TEXT("MyCharacter's Name is %s"), *MyCharacter->GetName() );

//其中%s 需要匹配类型为TCHAR*, 所以使用 *FString()

打印Bool

UE_LOG(YourLog,Warning,TEXT("MyCharacter's Bool is %s"), (MyCharacter->MyBool ? TEXT("True") : TEXT("False")));

 打印Int

UE_LOG(YourLog,Warning,TEXT("MyCharacter's Health is %d"), MyCharacter->Health );

 打印Float

UE_LOG(YourLog,Warning,TEXT("MyCharacter's Health is %f"), MyCharacter->Health );

打印FVector

UE_LOG(YourLog,Warning,TEXT("MyCharacter's Location is %s"), *MyCharacter->GetActorLocation().ToString());

打印FName

UE_LOG(YourLog,Warning,TEXT("MyCharacter's FName is %s"),  *MyCharacter->GetFName().ToString());

打印FString, Int,Float

UE_LOG(YourLog,Warning,TEXT("%s has health %d, which is %f percent of total health"), *MyCharacter->GetName(), MyCharacter->Health, MyCharacter->HealthPercent);

 

打印字体的颜色

灰色(普通日志信息)

UE_LOG(YourLog,Log,TEXT("This is grey text!"));

黄色(警告)

UE_LOG(YourLog,Warning,TEXT("This is yellow text!"));

红色(错误)

UE_LOG(YourLog,Error,TEXT("This is red text!"));

致命错误采用主动崩溃保护机制

如果你希望某段代码被正确的运行,你可以在不该运行代码的地方抛出一个致命错误,这样可以帮你确保你的算法不会出错,非常有用。

但是它看上去是一个崩溃,但是不用担心,看看崩溃的堆栈信息或许能帮你找到出错的原因。

 

快速打印提示

这是一个更简单的打印技巧,你需要在你的文件中声明,并include到使用的文件里

#define print(text) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White,text)

PrintString

PrintText 

PrintWarning

为了防止太多的相同打印,你可以将第一个参数设置为一个正数,UE4将会删除其他相同的打印内容,保持最新的日志信息。

其他打印方式

打印到屏幕

 #include <EngineGlobals.h>
 #include <Runtime/Engine/Classes/Engine/Engine.h>
 // ...
 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));
 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Some variable values: x: %f, y: %f"), x, y));

打印到客户端控制台

按下"~"键打开UE控制台,如果您使用PlayerController类,您可以将消息打印到这个控制台,这样做的好处是,它是一个完全不同的日志空间,不需要在游戏外设置选项卡即可轻松查看

日志关键字

  • [cat] = 命令操作的类别
  • [level] = verbosity level(详情级别), 包括:none, error, warning, display, log, verbose, all, default

有用的控制台命令

  • Log list - 列出所有的日志内别
  • Log list [string] - 列出所有的日志内别,包括一个子字符串
  • Log reset - 重置日志类别
  • Log [cat] - 切换显示的类别
  • Log [cat] off -  禁用日志类别
  • Log [cat] on -  开启日志类别
  • Log [cat] [level] - 设置日志类别的级别
  • Log [cat] break - 在显示类别上切换调试断点 

日志命令行

-LogCmds=\"[arguments],[arguments]...\"           - 启动时刻执行的命令行
-LogCmds=\"foo verbose, bar off\"                 - 打开foo类别并关闭bar类别

环境变量

每一条命令行都可以通过环境变量 "UE-CmdLineArgs"设置

set UE-CmdLineArgs=\"-LogCmds=foo verbose breakon, bar off\"   在环境变量中设置开启foo类别,关闭bar类别

配置文件

在UE项目目录./Config/DefaultEngine.ini或者Engine.ini中设置:

[Core.Log]
global=[default verbosity for things not listed later]
[cat]=[level]
foo=verbose break

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呦呦鹿鸣.

你的打赏是给予我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值