已标记USTRUCT的FCrusherTrigger结构体在C++中报错“type must be a UCLASS, USTRUCT or UENUM”但蓝图可正常使用的问题排查
兄弟,我之前也踩过一模一样的坑!明明结构体已经标了USTRUCT(BlueprintType),蓝图里用着完全没问题,C++编译却偏要报错,大概率是头文件引用或者前置声明的锅,给你捋几个最可能的原因和解决办法:
最常见的情况:BaseCrusher.h没包含FCrusherTrigger的定义头文件
编译器处理BaseCrusher里的TArray<FCrusherTrigger>时,根本不知道FCrusherTrigger是什么,更不知道它是个USTRUCT。你得在BaseCrusher.h的顶部,加上结构体所在头文件的引用,比如:#include "FCrusherTrigger.h" // 替换成你的结构体实际所在的头文件名别只加前置声明
struct FCrusherTrigger;!前置声明只能告诉编译器这是个结构体,但UE的反射系统需要完整的USTRUCT定义信息,前置声明满足不了这个需求。如果结构体在命名空间里:BaseCrusher里要正确引用命名空间
要是FCrusherTrigger放在自定义命名空间里(比如namespace MyGame),那声明TArray的时候得带上命名空间:TArray<MyGame::FCrusherTrigger> TriggersSetup;当然也可以在BaseCrusher.h里加
using namespace MyGame;,不过不推荐在头文件这么做,容易引发命名冲突。版本兼容小细节:替换旧的GENERATED宏
如果你用的是UE4.25及以上版本,建议把GENERATED_USTRUCT_BODY()换成GENERATED_BODY(),新版本UE更推荐后者,虽然旧宏可能还能用,但偶尔会出现反射信息不兼容的问题。修改后的结构体开头应该是:USTRUCT(BlueprintType) struct FCrusherTrigger { GENERATED_BODY() // 你的成员变量和构造函数... };
先试试第一种方法,这是90%概率能解决问题的原因——很多人写完结构体就忘了在使用的地方引头文件,尤其是蓝图能正常识别后,更容易忽略C++的编译依赖。
内容的提问来源于stack exchange,提问作者Elagin Dmitrii

