I have two classes QuestBase and QuestCondition.
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "QuestBase.generated.h"
UCLASS(Blueprintable)
class QUESTS_API AQuestBase : public AActor
{
GENERATED_BODY()
public:
AQuestBase();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Quest)
TArray <class UQuestCondition*> QuestConditions;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Quest)
TArray <class UObject*> UObjectQuestConditions;
};
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "QuestCondition.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class QUESTS_API UQuestCondition : public UObject
{
GENERATED_BODY()
public:
UQuestCondition();
};
Based on those two I created their child classes in blueprints.
I want to add one or more QuestConditions to the BP_Quest_1 but I can’t do it if they derive from UQuestCondition;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Quest)
TArray <class UQuestCondition*> QuestConditions;
if I change TArray <class UQuestCondition*> to something else like UObject or AActor then it works but not when it`s a class that derive from Uobject.
Am I missing some macro here?
I’ve found sort of solution.
replace
```
TArray <class UQuestCondition*> QuestConditions;
with
```
TArray <TSubclassOf<class UQuestCondition>> QuestConditions;
but I still would like to know why first case doesn’t work, because If I use class that derives from AActor or Character it works.
The syntax class UQuestCondition*
does not equate to a class type variable. It is essentially equivalent to UQuestCondition*
which means it’s a pointer to an instance of UQuestCondition object. If you had an UQuestCondition object constructed somewhere it the world/editor, it would probably show up in the picker. Generally, you should never set object references in class defaults. The only case where setting object references in a details panel is valid, is when you place an actor in the level and edit its properties to reference another actor in the level.
Class references are of type UClass*, and TSubclassOf is a wrapper for UClass* designed to enforce specific sub-classes.
It also works with UObject* because an UClass* is actually a child of UObject* under the hood, but it’s a crapshoot, and you’ll have to cast to UClass* everytime you want to use it.
Using TSubclassOf<UQuestCondition>
is the only proper solution here.
Thanku you for this explanation.