Unreal Engine 大象无形学习笔记 (第一部分:虚幻C++编程)

Q1. 什么时候继承自UObject类,什么时候声明纯C++类?

UObject自带功能:

1. 垃圾收集:继承自UObject并被标记为UProperty的变量,会被引擎自动进行生命周期管理。

2. Reference updating 引用自动更新

3. 反射

4. 序列化:纯C++类也可以手动实现

5. Automatic updating of default property changes 自动检测默认变量的更改

6. Automatic property initialization 自动变量初始化

7. Automatic editor integration 编辑器自动交互:在Editor里可直接编辑

8. Type information available at runtime 运行时类型识别 :Cast<>

9. 网络复制:在引擎加载阶段创建Default Object,构造函数被调用时,UWorld不一定存在,GetWorld()返回值可能为空!

Q2. 什么时候继承自Actor类?

需要挂载组件时。

Q3. 什么时候继承Pawn类,什么时候继承Character类?

需要移动组件继承Character类,不需要移动逻辑,比如飞船,继承Pawn类。

Q4. 怎么创建纯C++类并被UE识别?

1. 创建你的.h和.cpp文件,如果你是第一种文件结构,.h文件放在public文件夹内,.cpp文件放置在private文件夹内。
2. 在.h中声明你的类:如果你的类继承自UObject,你的类名上方需要加入UCLASS()宏。同时,你需要在类体的第一行添加GENERATED_UCLASS_BODY()宏,或者GENERATED_BODY()宏。前者需要手动实现一个带有const FObject Initializer&参数的构造函数。后者需要手动实现一个无参数构造函数。注意笔者说的是“实现”而非声明。
3. 在你的.cpp文件中,包含当前模块的PCH文件。一般是模块名+private PCH.h。如果是游戏模块,有可能包含的是游戏工程名.h。
4. 编译。
Q5. UE命名规则有哪些,怎么创建、获取、销毁各种类型的对象?
F 纯C++类
前缀 类型 创建对象 获取对象 内存管理
F 纯C++类 new  

delete

普通指针转换智能指针:

TSharedPtr<YourClass> YourClassPtr = MakeShareable(new YourClass());

U 继承自UObject,但不继承自Actor NewObject<T>()   自动垃圾回收,通过AddToRoot不被回收
A 继承自Actor GetWorld()->SpawnActor<ActorClass>()

for (TActorIterator<AStaticMeshActor> ActorIter(GetWorld()); ActorIter; ++ActorIter)
{
UKismetSystemLibrary::PrintString(GetWorld(), FString::Printf(TEXT("%s"), *ActorIter->GetName()));
}

 

TArray<AActor*> OutActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AStaticMeshActor::StaticClass(), OutActors);
for (AActor* actor : OutActors)
{
UKismetSystemLibrary::PrintString(GetWorld(), actor->GetName());
}

 

static void GetAllActorsWithTag(const UObject* WorldContextObject, FName Tag, TArray<AActor*>& OutActors);

 

static void GetAllActorsWithInterface(const UObject* WorldContextObject, TSubclassOf<UInterface> Interface, TArray<AActor*>& OutActors);

 

APlayerController* playerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);

 

APlayerController* playerController = GetWorld()->GetFirstPlayerController();

 

APawn* myPawn = Cast<ADrone>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));

 

APawn* myPawn = GetWorld()->GetFirstPlayerController()->GetPawn();

 

ACharacter* myPawn = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);

 

ACharacter* myPawn = GetWorld()->GetFirstPlayerController()->GetCharacter();

Destory()  只是从世界中销毁,内存还是系统自动回收

S Slate控件相关类 SNew    
H HitResult相关类      
Q6. 蓝图怎么调用C++?
注册变量到蓝图中:UPROPERTY(BlueprintReadWrite,VisibleAnyWhere,Category="Object")
注册函数到蓝图中:UFUNCTION(BlueprintCallable,Category="Test")   //BlueprintImplementEvent 表示由蓝图的子类实现   BlueprintNativeEvent C++默认实现可被蓝图重载,需要提供一个“函数名_Implement”函数实现于CPP中

Q7. 正则表达式

1) 添加头文件:#include "Regex.h"

2)构造函数:FRegexPattern

3)执行函数:FRegexMatcher

  常用:bool FindNext() 

Q8. 怎么获取游戏路径?

FPath::GameDir() //游戏根目录
FPath::FileExists() //判断文件是否存在
FPath::ConvertRelativePathToFull() //相对路径转换为绝对路径

Q9. XML与JASON怎么序列化与反序列化?

XML Parse工具:FastXML、FXmlFile

Q10.文件操作

获取路径:FPaths

读写:FPlatformFileManager

函数 作用
CopyDirectoryTree 递归拷贝目录
CopyFile 拷贝当前文件
CreateDirectory 创建目录
CreateDirectoryTree 创建一个目录树
DeleteDirectory 删除指定目录
DeleteDirectoryRecursively 递归删除指定目录
DeleteFile 删除指定文件
MoveFile 移动文件
DirectoryExists 检查目录是否存在
FileExists 检查文件是否存在
GetStateData 获得文件状态信息,返回FFileStatData类型对象
FileSize 获得文件大小,文件不存在返回-1
IterateDirectory 遍历目录
OpenRead 打开并读取文件,返回IFileHandle
OpenWrite 打开并写入文件

LoadFileToArray

LoadFileToString

将指定路径文件读取到TArray<uint8>数组

注意字符串有长度限制

SaveArrayToFile

SaveStringToFile

保存到指定文件

LoadANSITextFileToStrings

读取ANSI编码的文本到字符串数组中

 

Q11. 读写配置文件

GConfig->SetString(   //还有SetBool、SetInt、SetFloat等
    TEXT("Section"),
    TEXT("Key"),
    TEXT("Value"),
FPath::GameDir()/ "MyConfig.ini");
FString Result;
GConfig->GetString(
    TEXT("Section"),
    TEXT("Key"),
    Result,
    FPath::GameDir()/ "MyConfig.ini");

刷新缓冲区,马上生效:GConfig->Flush();

Q12. 怎么输出UE日志?

怎么查看LOG?打包后需要在启动参数加-log,编辑器运行需要打开Window->DeveloperTools->OutputLog

语法:UE_LOG(LogMy,Warning,TEXT("show a string:%s"),*FString("test"));

日志类型 输出颜色
Log 灰色
Warning 黄色
Error

红色

输出到游戏界面:

GEngine->AddOnDebugScreenMessage()

Q13. 怎么自定义Category?

将以下定义放在被多数源文件引用的文件里

DEFINE_LOG_CATEGORY_STATIC(LogMyCategory,Warning,All);

Q14. 虚幻引擎有哪些字符串类?

类型 特点
FName 数据结构是哈希表,所以是唯一的,大小写不敏感,不可修改
FText 数据结构是查找表,内置本地化支持,用作被显示的字符串,不可修改
FString 可修改

Q15. 虚幻引擎怎么跨平台?

平台相关工具函数类:FPlatformMisc 

eg. typedef FLinuxPlatformMisc FPlatformMisc; 

Q16. 怎么转换图片类型?

图片压缩后的数据:CompressedData

图片RGBA数据无压缩:RawData

ImageWrapper = CompressedData + RawData

怎么读取硬盘里的贴图?

 1 UTexture2D * FSystemToolsPublic::LoadTexture2DFromBytesAndExtension(const FString& ImagePath , uint8* InCompressedData ,int32 InCompressedSize ,int32 & OutWidth,int32 & OutHeight)
 2 {
 3     UTexture2D * Texture = nullptr;
 4     IImageWrapperPtr ImageWrapper = GetImageWrapperByExtention(ImagePath);
 5     if (ImageWrapper.IsValid() && ImageWrapper ->SetCompressed(InCompressedData , InCompressedSize))//读取压缩后的图片数据
 6     {
 7         const TArray <uint8>* UncompressedRGBA = nullptr;
 8         if (ImageWrapper ->GetRaw(ERGBFormat::RGBA, 8,UncompressedRGBA))//获取原始图片数据
 9         {
10             Texture = UTexture2D::CreateTransient(ImageWrapper ->GetWidth(), ImageWrapper ->GetHeight(), PF_R8G8B8A8);
11             if (Texture != nullptr)
12             {
13                 //通过内存复制,填充原始RGB数据到贴图的数据中
14                 OutWidth = ImageWrapper ->GetWidth();
15                 OutHeight = ImageWrapper ->GetHeight();
16                 void * TextureData = Texture->
17                 PlatformData ->Mips[0].BulkData.
18                 Lock(LOCK_READ_WRITE);
19                 FMemory::Memcpy(TextureData,
20                 UncompressedRGBA ->GetData(),
21                 UncompressedRGBA ->Num());
22                 Texture->PlatformData ->Mips[0].
23                 BulkData.Unlock();
24                 Texture->UpdateResource();
25             }
26         }
27     }
28     return Texture;
29 }
30 UTexture2D * FSystemToolsPublic::LoadTexture2DFromFilePath(FString & ImagePath,int32 & OutWidth,int32 & OutHeight)
31 {
32     //文件是否存在     
33     if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*ImagePath))
34     {
35         return nullptr;
36     }
37     //读取文件资源
38     TArray <uint8 > CompressedData;
39     if (!FFileHelper::LoadFileToArray(CompressedData , *ImagePath))
40     {
41         return nullptr;
42     }
43     return LoadTexture2DFromBytesAndExtension(ImagePath,CompressedData.GetData(), CompressedData.Num(), OutWidth,OutHeight);
44 }               

 

posted @ 2023-05-14 17:55  番茄玛丽  阅读(476)  评论(0编辑  收藏  举报