I’m coming from a C#/TypeScript and Go land, so bear with me. I’m building a turn-based game in which units can perform various actions. Think XCOM, but without the grid.
I want to have a base Command class (actor, I guess?) that would store three main informations: Invoker, the Target and the implementation of the action itself.
UCLASS()
class AVA_API AAvaAction : public AActor // does it even need to be a pawn?
{
GENERATED_BODY()
protected:
virtual void BeginPlay() override;
public:
AAvaAction();
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
AAvaBaseUnit* Invoker; // this is the "thing" that initiates the action.
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
T* Target; // this is the thing the action is initiated against, could be different things, see below for details.
void Execute(); // this would be implemented by inherited children Blueprints and would script the actual behaviour of the action based on the invoker, its player controller, etc.
virtual void Tick(float DeltaTime) override; // do i even need this?
};
Here is an example of what I’m trying to do. I want all possible things that a unit can do go through that pattern so I can implement a Command Pattern for undoing and redoing actions (and other things). I want the core functionality in C++ (mostly for learning) and then scripting of each action to be done as a blueprint.
Invoker will always be the pawn that initialises the action. But what about the Target? It can be another pawn (attack X, cast a spell on X, etc.), FVector (move to X) or even some non-pawn actor (cover behind X). How can I model that? In C# I’d use generics. Would a structure be a better choice?
To be honest, I don’t thing you are going on the right path here. You are trying to mix multiple different things under one variable. And then you would have to do bunch of if statements, or one big switch statement.
If this is AI, use behavior tree.
Use Single Responsibility Principle, create smaller portion (components) that you can port to multiple different actors. It is important to separate concerns so that those do not affect each other.
This isn’t really an answer. Maybe differently: how can I implement a Command Pattern in Unreal C++ so that I can store the actions in some place and then execute/undo them?
your commands are just holding/transferring information, so they dont need to exist in the level i think. Actor is a thing that exist in level (i.e. has transform). Pawn is child that can be possessed by player controller or AI controller.
the idea is you have a parent uobject class that holds whatever general functions you need (like reference to your invokers and targets).
Then you make a child instance of that class for any specific commands. that will delegate events/functions to your target.
I’m not a real programmer, just a blueprint guy, but in the end of that video the author covers c++ implementation and shows some architecture for using a command stack for undo.
Oh, that sounds exactly like something I needed. I was thinking about UObjects, that might be a good lead. Then I’d create blueprint child classes from that C++ base class with specific implementation (working in Blueprints is just faster for stuff like that, iteration time can’t be beaten). I can see him having a transaction log, where he keeps the commands on a stack. Thanks a lot!
he has another video covering a state pattern as well - not what you are looking for here but it shares some similar principles so if you just looking for a little more examples of general programming principles applied in unreal, that may be handy.
oh and one thing you’ll probably want to look into more is what is the lifespan of the uobject? I think if it is not cached as a variable it may be automatically garbage collected, so if you need some data that persist you wouldn’t want to leave it in the uobject (or otherwise cahce the object as a variable to be held by something like the player controller).
that stuff is a little over my head but i know that in some circumstances it may be important to consider