c++ 虚幻引擎反射 c++ ue的uproperty和ufunction如何工作

夜浩大大_9913

夜浩大大_9913

2026-03-26

295人浏览

原创

ue通过uht编译器插件解析uproperty()宏生成反射代码,要求类继承uobject、字段类型合法、元数据正确,且必须完整重建工程才能生效。

c++ 虚幻引擎反射 c++ ue的uproperty和ufunction如何工作

UProperty 在 C++ 里怎么被 UE 看见

UE 的反射系统不是靠运行时扫描符号表,而是靠编译器插件(UnrealHeaderTool)在构建前期解析 C++ 头文件,提取 UPROPERTY() 宏标记的成员变量信息,生成额外的 C++ 代码(比如 StaticClass()、GetDefaultObject() 相关逻辑),再让原生 C++ 类“带反射能力”地参与引擎生命周期。

常见错误现象:UPROPERTY() 写在 private 区域但没加 public: 或 protected: 前缀,UHT 直接跳过;或者用了不支持的类型(比如裸指针 MyStruct* 而非 TObjectPtr<mystruct></mystruct>),导致编译通过但编辑器里不显示、GC 不回收。

  • UPROPERTY() 必须写在类定义内,且所在类需继承自 UObject 或其子类
  • 基础类型(int32、FString)、引擎容器(TArray、TMap)、UObject 派生类指针(UTexture2D*)都支持,但原生 STL 容器(std::vector)和裸 C++ 类型(MyCustomStruct)必须加 USTRUCT() 且字段也用 UPROPERTY()
  • 编辑器可见性依赖元数据,比如 UPROPERTY(EditAnywhere) 才能在细节面板改,漏写元数据就等于“反射了但不可见”

UFunction 怎么让蓝图调用到 C++ 函数

UFUNCTION() 不是魔法钩子,它只是告诉 UHT:“这段函数签名要导出”,UHT 随后生成一个 UFunction 对象描述符,并在类的 StaticClass() 初始化阶段注册进反射表。蓝图调用时,引擎不直接 call C++ 函数指针,而是走统一的 UFunction::Invoke() 调度路径,中间完成参数压栈、GC 引用管理、线程检查等。

使用场景:想让蓝图调用、想在编辑器里设为事件响应、想用 CallFunctionByNameWithArguments 动态触发——这些都强依赖 UFUNCTION() 及其元数据。

  • 函数必须是 UCLASS 内的成员函数,不能是 static 或 free function
  • 返回值只能是 void 或基本/引擎支持类型(bool、FVector、UObject*),不支持 std::optional 或引用返回
  • 参数列表不能有默认值(int32 X = 5 会报错),也不能有未标记 const& 的非 UObject 指针参数(UHT 解析失败)
  • 想在蓝图中暴露为事件,得加 BlueprintImplementableEvent;想允许蓝图重写,得加 BlueprintNativeEvent;漏掉这两者之一,蓝图节点就出不来

为什么改了 UPROPERTY 却没出现在编辑器里

不是代码写错,大概率是构建流程卡在中间环节:UHT 没重新运行,或生成的 *.generated.h 文件没被包含,或类没加 UCLASS() 导致整个反射上下文缺失。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

性能影响很小,但兼容性陷阱明显:比如在构造函数里直接读 UPROPERTY() 初始值,实际此时反射数据还没加载(PostInitProperties() 才算真正初始化完毕),拿到的是零值;又比如在 BeginPlay() 之前用 GetClass()->FindPropertyByName() 查找字段,可能返回 null——因为 UClass 还没完全初始化。

  • 每次修改 UPROPERTY() 或 UFUNCTION() 后,必须重新生成 Visual Studio 工程(GenerateProjectFiles.bat)并完整 rebuild,否则 *.generated.h 不更新
  • 确保头文件末尾有 #include "YourClass.generated.h",且该行必须在所有其他 include 之后
  • 如果类从 UObject 改成 UActorComponent 或反过来,记得检查基类宏是否匹配(UCLASS() 对应 UObject,UCLASS(ClassGroup=...) 才支持 Actor 子类)

反射数据什么时候能安全访问

不是所有生命周期都能随便查反射信息。UClass 和 UProperty 指针在 StaticClass() 返回前都是空的;而对象实例的属性值,在 PostInitProperties() 之后才被反射系统真正赋初值(包括 ConstructorHelpers 加载的资源)。

容易踩的坑:在 AActor::AActor() 构造函数里调用 GetClass()->FindPropertyByName(),返回 null;或在 BeginDestroy() 里还试图访问 UPROPERTY() 字段,此时 GC 可能已清空引用。

  • 安全访问反射结构体(UClass、UProperty)的最早时机是 StaticClass() 调用后,典型位置是 UCLASS() 宏展开后的静态初始化块
  • 安全访问实例属性值的最早时机是 PostInitProperties(),常见做法是在该函数里做反射驱动的初始化(比如根据某个 UPROPERTY(EditAnywhere) 的值自动创建子组件)
  • 运行时动态查找字段请用 FindField<uproperty>(Class, TEXT("FieldName"))</uproperty>,别硬写 Cast<uproperty>(Class->FindPropertyByName(...))</uproperty> ——类型不匹配会 crash

反射不是实时的,它是一次性构建 + 运行时只读查询。最常被忽略的是:你改了 C++ 里的 UPROPERTY() 名字,但蓝图里还连着旧名字的引脚,这时候编辑器不会报错,只会静默断开——得手动重连。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1698

6

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2258

7

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

4854

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5011

25

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

4854

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5011

25

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.23

636

5

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.27

371

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习