Welcome to third part of this series. We are creating a reusable health system using interfaces in C++ and use that on many actors. It will be an ActorComponent. If you haven't read the first part yet, do so. Second part is not required.
For a health system, we would need,
Following what we discussed before, We start with the following code. (Removing the obvious #include sections)
//////////////////////////////////////////////////////////////////////
// UWW_HealthInterface.h
UCLASS()
class XYZ_API UWW_HealthInterface : public UInterface {
GENERATED_BODY()
};
class XYZ_API IWW_IBaseSceneComponent {
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Overrides")
int ReduceHealth(int Value); // will reduce HP, returns 1 if HP below zero
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Overrides")
int AddHealth(int Value); // will increase HP, returnas 1 if HP overflows
};
We implement this in an ActorComponent. This time we don't need to spawn it in world, so a ActorComponent suffices.
//////////////////////////////////////////////////////////////////////
// Appended to UActorComponent_HP.h
public:
// Called when any component property is modified in inspector
virtual void PostEditChangeProperty(FPropertyChangedEvent &PropertyChangedEvent) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int Health = 0;
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Override")
int ReduceHealth(int Value);
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Override")
int AddHealth(int Value);
virtual void ReduceHealth_Implementation() override;
virtual void AddHealth_Implementation() override;
//////////////////////////////////////////////////////////////////////
// Appended to UActorComponent_HP.cpp
void UActorComponent_H::PostEditChangeProperty(FPropertyChangedEvent &PropertyChangedEvent) {
Execute_AddHealth(this, 30);
Execute_ReduceHealth(this, 20);
}
int UActorComponent_H::ReduceHealth_Implementation(int Value) {
UE_LOG(LogTemp, Warning, TEXT("Interface ReduceHealth is not implemented."));
}
int UActorComponent_H::AddHealth_Implementation(int Value) {
UE_LOG(LogTemp, Warning, TEXT("Interface AddHealth is not implemented."));
}
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
or whatever is there to UCLASS(Blueprintable)
in UActorComponent_HP.h
Update: Okay, I figured that if we don't define the functions in C++, they come up as regular functions in blueprint (with purple noides). This means, it is as if the function was never implemented in C++. Regardless, we will continue putting dummy functions in C++ as we did, because the message will throw NotImplemented warning rather than break the code.
After this is done, compile and jump to blueprint. Override the 2 interfaces, drag and attach the property and increment/decrement by value. It is a very simple exercise. It will add 2 functions. If you have difficulty, just fire up the included example. C++ guys can just write out the code in XYZ_Execute functions. To kill the actor, use (From ActorCompoennt code)
``
That was all the basics covered. I hope you consider including abstract C++ interfaces in your future projects. Anything new added to this series will feature integrating other important features (like GameplayAbilitySystem, ThirdPartyPlugins). You can always check for additional posts from the module page or homepage.
If you would like some important feature covered and added to this module, please drop me a mail
I upload weekly and revamp bi-monthly. You can support my work at Patreon | Paypal | Marketplace | Gumroad