Hello everyone,
I’m working on a small side project that has RTS controls. When the player clicks on a unit and then clicks on another unit, the unit should perform an action so I thought I would implement an action system. What I’ve done so far is create an Action_Base class derived from UObject, it has some basic logic like:
//returns true or false based on whether or not we can perform an action on this object
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Action")
bool CanPerformActionOn(UObject * obj);
//Requests that we do the action on the specified object - mostly meant to handle timer logic
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Action")
bool RequestActionOn(UObject * obj);
//Does the specific action stuff
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Action")
void DoAction() const;
//fires off when the action succeeded
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Action")
void ActionSucceeded() const;
//fires off when the action failed
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Action")
void ActionFailed() const;
The unit has this:
//actions this agent comes with
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Actions")
TArray<TSubclassOf<UAction_Base>> actionClasses;
//the actual actions
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Actions")
TArray<UAction_Base *> actions;
When the unit is created, I initialize its actions as follows:
for (int i = 0; i < actionsToSpawn.Num(); i++)
{
UAction_Base * newAction = NewObject<UAction_Base>(this, NAME_None, RF_NoFlags, actionsToSpawn[i].GetDefaultObject());
if (newAction)
actions.AddUnique(newAction);
}
I then went into unreal and made a blueprint subclass of Action_Base called DebugPrintStringAction. All it is meant to do is print “hello” when the unit performs the action. I overwrote the functions above and added printstrings in them.
When the time comes and I call RequestActionOn, it fires the C++ logic, but not the specific blueprint logic I overwrote. It seems the actions that are created are Action_Base classes and they are unaware of the subclass that was passed in the TSubclassOf variable. I even tried casting the created action to the specific subclass then calling the function but the cast always fails which tells me I don’t seem to understand what TSubclassOf is meant to do or I am using it wrong.
Does anyone have any pointers on this? I thought it might be strange that I am using objects? Is there something else I should use for something like this? Is there something fundamentally wrong with how I am understanding the whole TSubclassOf an object and how I am creating it?
Thanks for the help!