UFUNCTION必须显式添加BlueprintCallable、BlueprintImplementableEvent等标识才能在蓝图中显示,参数类型需为UObject派生类、FStruct或基础UProperty类型,函数不可重载、无默认参数,返回值仅限void或蓝图可识别类型,类须继承UObject/AActor并正确使用UCLASS宏。

UFUNCTION宏必须加BlueprintCallable或BlueprintImplementableEvent才能在蓝图中看到
不加任何功能标识的UFUNCTION,哪怕写了BlueprintCallable拼错成BlueprintCallble,蓝图编辑器里也完全不会显示这个函数。UE只认明确声明的执行权限和暴露策略。
常见错误现象:UFUNCTION()编译通过,但蓝图节点搜索不到、右键菜单不出现、拖出引脚时提示“function not found”。
-
BlueprintCallable:C++实现逻辑,蓝图可调用(最常用) -
BlueprintImplementableEvent:C++留空,蓝图中重写逻辑(类似虚函数) -
BlueprintNativeEvent:C++提供默认实现,蓝图可选择覆盖(需额外实现FunctionName_Implementation)
参数类型必须是UObject派生类、FStruct或基础UProperty类型
UE蓝图系统无法序列化或传递任意C++类型。比如std::string、std::vector<int>、裸指针int*、或未标记USTRUCT的自定义结构体,都会导致编译失败或蓝图中参数消失。
使用场景:想传一个坐标偏移量?必须用FVector而不是glm::vec3;想传一组ID?用TArray<int32>而不是std::array<int, 3>。
立即学习“C++免费学习笔记(深入)”;
- 基础类型:
int32、float、bool、FString、FName、FText - 容器:仅
TArray<T>(且T本身也得是蓝图友好类型) - 结构体:必须加
USTRUCT(BlueprintType)并生成反射(含GENERATED_BODY()) - 对象引用:必须是
UCLASS且带BlueprintType或Blueprintable元数据
函数签名里不能有默认参数,也不能重载同名UFUNCTION
UE的反射系统不支持默认参数解析——哪怕你在C++里写了void MyFunc(int32 Value = 42),蓝图里仍会要求你连入所有参数,且默认值不生效。更糟的是,如果两个UFUNCTION同名(哪怕参数不同),编译会直接报错:Redefinition of UFUNCTION 'MyFunc'。
- 替代方案:拆成不同函数名,如
MyFunc_Simple()和MyFunc_Advanced() - 需要可选行为?用
bool bUseAdvancedMode参数代替,默认值逻辑在C++里写死 - 返回值只能有一个,且必须是蓝图可识别类型(
void或上述允许类型)
类必须继承自UObject或AActor,并正确添加UCLASS宏
只有UCLASS标记的类才能参与蓝图反射。比如你写了个纯工具类class FMyHelper,哪怕加了UFUNCTION也毫无意义——它根本不会被UHT(Unreal Header Tool)扫描。
性能影响:每个UFUNCTION都会增加反射数据体积和启动时的注册开销,非必要不滥用。尤其避免在每帧调用的函数上加BlueprintCallable。
- Actor类:加
UCLASS()即可,蓝图中作为“事件分发者”最自然 - 纯数据/工具类:必须是
UCLASS(BlueprintType),且通常配合StaticClass()在蓝图中作为静态调用目标 - 忘记
GENERATED_BODY()?编译失败,错误信息类似:error C2039: 'StaticClass' : is not a member of 'UMyClass'
最容易被忽略的是UHT处理时机:改完UFUNCTION后必须保存头文件并触发重新生成VS项目(或等编辑器自动重编译),否则蓝图里看不到更新。有时候改了参数类型,但没清掉Intermediate和Saved目录,也会卡在旧反射状态里。


















