【UE】UE中常用功能代码

在UE中,经常由于测试的需要,需要临时添加一些辅助函数或者一些辅助代码,这些代码不太适合直接提交到项目里,因此这里开个文章作为记录,避免每次重头查阅资料。

1. 函数

1.1 堆栈打印函数

用于输出当前点的函数调用堆栈,实现代码给出如下:

#include "HAL/PlatformStackWalk.h"
void PrintCallStack()
{
    ANSICHAR* StackTrace;

    const SIZE_T StackTaceSize = 65535;
    StackTrace = (ANSICHAR*)FMemory::Malloc(StackTaceSize);
    StackTrace[0] = 0;
    FPlatformStackWalk::StackWalkAndDump(StackTrace, StackTaceSize, 0);
    FString StackTraceText(StackTrace);
    TArray<FString> StackLines;
    StackTraceText.ParseIntoArrayLines(StackLines);
    UE_LOG(LogTemp, Error, TEXT("-----------Call Stack---------------------"));
    for(FString& StackLine : StackLines)
        UE_LOG(LogRHI, Error, TEXT("\t %s"), *StackLine);

}

2. 调试

2.1 关闭代码优化

UE引擎的代码优化开关跟普通Visual Studio项目的代码优化开关不太一样,这个开关是通过在Build.cs文件中进行定义来实现对单个模块的优化控制的:

如上图所示,当我们需要关闭某个模块的代码优化时,只需要在此模块所对应的ModuleRules子类的构造函数中添加:

OptimizeCode = CodeOptimization.Never;

即可关闭优化。

2.2 弹窗log

在真机上弹窗显示消息

FPlatformMisc::MessageBoxExt(EAppMsgType::Ok, TEXT(
  "Failed to find all required Vulkan entry points! Try updating your driver."), TEXT("No Vulkan entry points found!"));

2.3 屏幕信息打印

// Clear all screen messages
GEngine->ClearOnScreenDebugMessages();

// Add Screen Message
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, PosMsg);

2.4 调用命令行命令

// Enable Screen Message
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), TEXT("EnableAllScreenMessages"), GetWorld()->GetFirstPlayerController());

3. 类型相关

3.1 FString

3.1.1 FString转char*

FString FilePath("Good Enough");
char* Prefix = TCHAR_TO_ANSI(*FilePath);

4. 功能

4.1 文件IO

文件及路径操作,UE集成了一些函数可供使用,具体可以参考如下的一些Class:
1. FPaths Class
2. FFileManagerGeneric

4.2 文件引用

4.2.1 ThirdParty头文件引用

第三方库头文件引用需要通过宏进行包裹(HlslccHeaderWriter.cpp):

THIRD_PARTY_INCLUDES_START
#include "spirv_reflect.h"
THIRD_PARTY_INCLUDES_END

可能会遇到文件找不到的报错,可以打开对应Module的Build.cs文件,添加对应的Include Path(ShaderCompilerCommon.Build.cs):

  PublicSystemIncludePaths.Add("ThirdParty/hlslcc/hlslcc/src/hlslcc_lib");
  PublicSystemIncludePaths.Add("ThirdParty/SPIRV-Reflect/SPIRV-Reflect");

到这里还没结束,因为只有头文件而没有实现,会报错 unresolved external symbol xxx之类的,此时还需要添加对应的lib文件:

if (UnrealTargetPlatform.Win32 == Target.Platform || UnrealTargetPlatform.Win64 == Target.Platform) //decide the platform to package the binaries
{
      PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, "LibraryBinariesFolder", "Windows", "liblibrary.lib")); //the full path is "LibraryBinariesFolder/Windows/liblibrary.lib"
}
else if (UnrealTargetPlatform.Android == Target.Platform)
{
     PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, "LibraryBinariesFolder", "Android", "armeabi-v7a", "liblibrary.a")); //the full path is "LibraryBinariesFolder/Android/armeabi-v7a/liblibrary.a"
     PublicAdditionalLibraries.Add(Path.Combine(ModuleDirectory, "LibraryBinariesFolder", "Android", "arm64-v8a", "liblibrary.a")); //the full path is "LibraryBinariesFolder/Android/arm64-v8a/liblibrary.a"
}

更多可以参考How to include any Third-Party library in Unreal Engine 4

4.3 其他

4.3.1 定时器

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
    GENERATED_BODY()

public:
    AMyActor();

protected:
    virtual void BeginPlay() override;

private:
    FTimerHandle TimerHandle;
};

#include "MyActor.h"

AMyActor::AMyActor()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    // Set the timer to call a lambda function after a 5-second delay
    GetWorld()->GetTimerManager().SetTimer(TimerHandle, [this]()
    {
        UE_LOG(LogTemp, Warning, TEXT("Lambda function called!"));
    }, 5.0f, false);
}

未完待续...

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

推荐阅读更多精彩内容