Unreal Engine

反射宏

初步学习反射宏,记录内容,主要是一些基础

================================================================================

                    UE4 反射系统三大宏 总结笔记

================================================================================

 

一、核心概念:什么是反射系统?

--------------------------------------------------------------------------------

UE4 在标准 C++ 之上构建了一套反射系统(Reflection System),让引擎在

运行时能“知道”一个类有哪些属性、哪些方法。

 

你写的 UCLASS / UPROPERTY / UFUNCTION 宏,就是在向引擎登记:

“这个类 / 属性 / 函数,请纳入你的管理。”

 

编译前,Unreal Header Tool (UHT) 会扫描这些宏,自动生成包含类型信息、

序列化、网络复制等功能的“元代码”,和你的纯 C++ 逻辑缝合在一起。

 

这就是你在编辑器中能编辑数值、在蓝图中能连线调用函数、在网络上能自动

同步数据的根本原因。

 

================================================================================

 

二、UCLASS() —— 登记一个类

--------------------------------------------------------------------------------

【作用】

放在类声明上方,告诉引擎:这个类可以被反射管理。

 

【常见说明符】

Blueprintable       允许从这个 C++ 类创建蓝图子类

BlueprintType       允许把该类的实例作为蓝图变量

Abstract            抽象类,不能直接在关卡里放置实例

NotBlueprintable    禁止创建蓝图子类

ClassGroup=…      在新建类向导里分组

 

【留空的后果】

不报错,但默认是 NotBlueprintable(不能创建蓝图子类)。

不过部分父类(如 UGameInstance)内部标记了 IsBlueprintBase=true,

子类会继承这个许可,所以留空也可能“碰巧”能创建蓝图子类。

→ 绝对不要依赖默认行为,需要被蓝图继承就显式写 Blueprintable。

 

【示例】

UCLASS(Blueprintable, Abstract)

class NETTEST_API UMyBaseActor : public AActor

{

    GENERATED_BODY()

};

 

================================================================================

 

三、UPROPERTY() —— 登记一个成员变量

--------------------------------------------------------------------------------

【作用】

放在成员变量声明前,让该变量拥有引擎特性,包括:

- 在编辑器中可见 / 可编辑

- 在蓝图中可读写

- 参与网络复制

- 参与序列化(保存、加载)

 

【常见说明符】(可组合使用)

EditAnywhere            编辑器中任何地方都可编辑

EditDefaultsOnly        只在类的默认值设置中可编辑

EditInstanceOnly        只在关卡中放置的实例上可编辑

VisibleAnywhere         编辑器中可见但不可编辑

BlueprintReadOnly       蓝图可读,不可写

BlueprintReadWrite      蓝图可读写

Category = ”…”        在细节面板中归类显示

Replicated              参与网络复制(须配合 GetLifetimeReplicatedProps)

Transient               不参与序列化(临时数据)

 

【留空的后果】

编译不报错,但该属性在编辑器中不可见、蓝图中不可读写,等于白写。

 

【示例】

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Stats”)

float Health;

 

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Replicated)

int32 KillCount;

 

================================================================================

 

四、UFUNCTION() —— 登记一个成员函数

--------------------------------------------------------------------------------

【作用】

放在函数声明前,让该函数拥有引擎特性,包括:

- 被蓝图调用或重写

- 成为网络 RPC(Server / Client / NetMulticast)

 

【极常用说明符】

BlueprintCallable               蓝图可调用

BlueprintImplementableEvent     蓝图实现(C++ 只声明,不实现)

BlueprintNativeEvent            C++ 提供默认实现,蓝图可重写

Server                          RPC:客户端调用,服务器执行

Client                          RPC:服务器调用,拥有者客户端执行、

NetMulticast                    RPC:服务器调用,所有客户端执行

WithValidation                  配合 Server,需要实现验证函数防作弊

Reliable                        可靠 RPC(保证送达,必须与 Server/Client 一起用)

Unreliable                      不可靠 RPC(不保证送达)

Category = ”…”                在蓝图右键菜单中归类

 

【留空的后果】

编译不报错,但蓝图右键菜单里完全找不到该函数,只能作为 C++ 内部函数使用。

 

【示例】

UFUNCTION(BlueprintCallable, Category = “Combat”)

void Attack();

 

UFUNCTION(Server, Reliable, WithValidation)

void ServerAttack();

 

================================================================================

 

五、核心法则总结

--------------------------------------------------------------------------------

1. 加宏就是在“贴标签”,告诉引擎你需要什么能力。

2. 宏的括号留空 = 放弃对应功能,不会报错但几乎什么都做不了。

3. UPROPERTY 和 UFUNCTION 绝对不能留空,否则编辑器/蓝图无法使用。

4. UCLASS 需要蓝图继承就必须显式写 Blueprintable,别依赖父类的默认许可。

5. GENERATED_BODY() 和 .generated.h 是反射系统的入口,一个都不能少。

 

================================================================================