Reputation: 2210
While it is well documented how TSubclassOf<>
can be used to declare a property that will only accept instances of a known C++ class, I'm in the situation where I would like my C++ AActor
-derived class to contain a property that will only accept references to instances of a specific Blueprint. (That Blueprint comes from a package that does not provide C++ header files.)
Upvotes: 1
Views: 4892
Reputation: 422
This is an interesting question so I wanted to provide one possible answer, which is a workaround with a minimal derived BP class and property reflection. I'm writing this without the engine available for compilation, so apologies if I've gotten anything wrong.
UCLASS(Blueprintable)
class AMyActor : public AActor
{
GENERATED_BODY()
public:
// Name of the required blueprint class property, which must be added in a derived blueprint
constexpr FName ClassPropertyName = TEXT("BlueprintClass")
protected:
/* Get the value of the blueprint class property. */
UClass* GetBlueprintClass();
};
UClass* AMyActor::GetBlueprintClass()
{
FObjectProperty* BlueprintClassProperty = FindFProperty<FObjectProperty>(GetClass(), ClassPropertyName);
checkf(BlueprintClassProperty != nullptr, TEXT("AMyActor must used via a derived BP type with a %s property."), *ClassPropertyName.ToString()))
UObject* PropertyValue = BlueprintClassProperty->GetObjectPropertyValue_InContainer(this);
if (PropertyValue != nullptr)
{
return CastChecked<UClass>(PropertyValue);
}
return nullptr;
}
You should be able to derive this in BP and add the required BlueprintClass property. There's no other logic required on the BP side, you just get the value of the property using the GetBlueprintClass method in C++. There's a little overhead there, so you may want to cache the value e.g. on actor construction or BeginPlay.
Upvotes: 2