假定有如下继承自AActor类的.h文件:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MoveRandom.generated.h"
UCLASS()
class DEMO01_API AMoveRandom : public AActor
{
GENERATED_BODY()
public:
AMoveRandom();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
private:
FVector initLocation;
FVector targetLocation;
FVector GetRandomLocation();
UStaticMeshComponent* staticMeshComponent;
UStaticMesh* staticMesh;
UMaterial* material;
};
1)#include "CoreMinimal.h"
CorMinimal.h来自于“Engine/Source/Runtime/Core/Public/CoreMinimal.h”,里面包含了大量常用的基础类,包括:字符串String(如:FString、FName)、数学Math(如:FVector、FColor)、容器Container(如:TSet、TArray)、日志Logging、代理Delegates等等。可以说没有这个库,几乎寸步难行。大多数情况下就是闭着眼睛继承就好了。
2)#include "GameFramework/Actor.h"
Actor.h来自于“Engine/Source/Runtime/Engine/GameFramework/Actor.h”,由于是基于AActor类生成的源代码,所以自然包含AActor的头文件。其实通过查看UE的API会发现,AActor的属性和方法嗷嗷多(是滴,你没看错,多得配得上“嗷嗷”这个形容词),UE自身继承自AActor的类有360多个(只能汗一个),对于UE日常编程来说,继承AActor类的情况是比较多的。有些开发者甚至说场景蓝图(Level Blueprint)里面不要添加内容,其相关的功能都可以用继承自AActor的类来搞定,因为这样方便功能在各个Level中重复使用,嗯,不得不说,似乎有点儿道理。
3)#include "MoveRandom.generated.h"
这个是专门为MoveRandom这个类生成的文件(感觉VIP待遇,有木有?),其后面的“.generated.h”这个内容是不变的,前面的“MoveRandom”内容保持和所建立的类名相同。对应的.cpp文件是“MoveRandom.gen.cpp”,不是“MoveRandom.generated.cpp”,呵呵。所在目录是“Intermediate\Build\Win64\UnrealEditor\Inc\Demo01\UHT”,其中“Demo01”是工程名,文件里面具体内容我看了头大,知道虚幻所生成的所有“反射数据”都会放入到该文件当中就好了。
特别提醒:#include“xxxxxx.generated.h"必须在所有#include宏语句最下部,否则报错
特别提醒:#include“xxxxxx.generated.h"必须在所有#include宏语句最下部,否则报错
特别提醒:#include“xxxxxx.generated.h"必须在所有#include宏语句最下部,否则报错
重要的事情说三遍,至于具体原因,我想是因为xxxxxx.generated.h的内容会用到所有上面被include的文件内容吧。
补充一下关于反射的内容:
反射是指在运行状态下,任意一个实体类都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为语言的反射。
C++本身并不支持反射,虚幻在C++上搭建了自己的一套反射机制。虚幻使用反射可以实现多种功能,包括:序列化Serialization、Editor中的细节面板、GC垃圾回收、网络复制、蓝图/C++ 通信和相互调用等等。