如何在Unreal C++中访问Blueprint类BP_EquipmentBase?
先讲清楚核心问题:C++代码编译的时候,根本不知道你在编辑器里创建的BP_EquipmentBase蓝图是什么,所以直接写BP_EquipmentBase*肯定会报未定义错误——蓝图是C编译完之后才在编辑器里做的派生类,C认不了它的自定义类名。
正确做法(其实没你想的那么麻烦)
先创建一个极简的C++基类
比如建个AEquipmentBase(如果你的蓝图是Actor类型)或者UEquipmentBase(如果是Object类型),代码超级简单,不需要额外逻辑:#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "EquipmentBase.generated.h" UCLASS() class YOURPROJECT_API AEquipmentBase : public AActor { GENERATED_BODY() public: AEquipmentBase(); };#include "EquipmentBase.h" AEquipmentBase::AEquipmentBase() { PrimaryActorTick.bCanEverTick = false; }让
BP_EquipmentBase继承这个C类
打开你的蓝图,在细节面板里把父类改成AEquipmentBase就行;如果是新建蓝图,直接选择这个C类作为父类。在玩家类里用基类声明变量
现在就可以在C++玩家类里正常声明变量了,记得先包含基类的头文件:#include "EquipmentBase.h" UPROPERTY(EditAnywhere, BlueprintReadOnly) AEquipmentBase* CurrentItem; UPROPERTY(EditAnywhere, BlueprintReadOnly) TArray<AEquipmentBase*> HeldEquipment;编译完成后,你就能在编辑器里把
BP_EquipmentBase的实例拖进这些变量里。后续如果要实现拾取、丢弃、使用的逻辑,直接在C++基类里定义虚函数,再在蓝图里重写即可。
顺便说下TSubclassOf的用途
如果你需要存储物品的类(而非实例),比如用来动态生成新物品,那就用TSubclassOf<AEquipmentBase>,示例代码:
UPROPERTY(EditAnywhere, BlueprintReadOnly) TSubclassOf<AEquipmentBase> DefaultEquipmentClass;
这样在编辑器里选择BP_EquipmentBase作为这个类变量的值后,就能在C++里通过GetWorld()->SpawnActor<AEquipmentBase>(DefaultEquipmentClass)生成物品实例。
为啥不能跳过这个C++基类?
UE的蓝图系统完全基于C++,所有蓝图类都必须继承自某个C类(哪怕是最基础的AActor或UObject)。C只能识别自己编译过的类型,无法直接识别编辑器中创建的蓝图自定义类名,所以必须通过这个C++基类作为中间层,才能实现类型安全的访问。
内容的提问来源于stack exchange,提问作者Kane Mattsuki

