Hi all,
I have a custom damage interface that I like to use. Problem is, I currently can’t use it in Blueprints with default implementation it seems. Is there a way to get around this somehow? What would be the best thing I could do to get it so I can have interfaces with default impelementations that are usable in C++ and blueprint? Right now, it won’t even let me implement in blueprint (due to CannotImplementInterfaceInBlueprint, but I get other errors if I remove this meta tag).
DamageableInterface.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "DamageableInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UDamageableInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class HALOFLOODFANGAME01_API IDamageableInterface
{
GENERATED_BODY()
public:
UFUNCTION()
virtual float CustomOnTakeAnyDamage(float DamageAmount, FVector Force, AController* EventInstigator = nullptr, AActor* DamageCauser = nullptr);
UFUNCTION(BlueprintCallable)
virtual float CustomTakeDamage(float DamageAmount, FVector Force, FDamageEvent const& DamageEvent, AController* EventInstigator = nullptr, AActor* DamageCauser = nullptr);
UFUNCTION(BlueprintCallable)
virtual float CustomTakePointDamage(FPointDamageEvent const& PointDamageEvent, float Force, AController* EventInstigator = nullptr, AActor* DamageCauser = nullptr);
UFUNCTION(BlueprintCallable)
virtual float CustomTakeRadialDamage(float Force, FRadialDamageEvent const& RadialDamageEvent, AController* EventInstigator = nullptr, AActor* DamageCauser = nullptr);
UFUNCTION(BlueprintCallable)
virtual UHealthComponent* GetHealthComponent();
UFUNCTION(BlueprintCallable)
virtual float ChangeHealth(float Damage, FVector Force = FVector(0,0,0), FVector HitLocation = FVector(0,0,0), FName HitBoneName = "", AController* EventInstigator = nullptr, AActor* DamageCauser = nullptr, bool bIgnoreShields = false, bool bIgnoreHealthArmor = false, bool bIgnoreShieldArmor = false);
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
};
DamageableInterface.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "DamageableInterface.h"
#include "HealthComponent.h"
#include "Core/CharacterBase.h"
#include "Engine/DamageEvents.h"
#include "Kismet/GameplayStatics.h"
// Add default functionality here for any IDamageableInterface functions that are not pure virtual.
float IDamageableInterface::CustomOnTakeAnyDamage(float DamageAmount, FVector Force,
AController* EventInstigator, AActor* DamageCauser)
{
return DamageAmount;
}
float IDamageableInterface::CustomTakeDamage(float DamageAmount, FVector Force, FDamageEvent const& DamageEvent,
AController* EventInstigator, AActor* DamageCauser)
{
return ChangeHealth(DamageAmount, Force, FVector(0,0,0), FName(""), EventInstigator, DamageCauser);
}
float IDamageableInterface::CustomTakePointDamage(FPointDamageEvent const& PointDamageEvent, float Force,
AController* EventInstigator, AActor* DamageCauser)
{
return ChangeHealth(PointDamageEvent.Damage, PointDamageEvent.ShotDirection * Force, PointDamageEvent.HitInfo.Location, PointDamageEvent.HitInfo.BoneName, EventInstigator, DamageCauser);
}
float IDamageableInterface::CustomTakeRadialDamage(float Force,
FRadialDamageEvent const& RadialDamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
return ChangeHealth(RadialDamageEvent.Params.BaseDamage, (Cast<AActor>(this)->GetActorLocation() - RadialDamageEvent.Origin).GetSafeNormal() * Force, FVector(0,0,0), FName(""), EventInstigator, DamageCauser);
}
UHealthComponent* IDamageableInterface::GetHealthComponent()
{
return Cast<AActor>(this)->FindComponentByClass<UHealthComponent>();
}
float IDamageableInterface::ChangeHealth(float Damage, FVector Force, FVector HitLocation, FName HitBoneName,
AController* EventInstigator, AActor* DamageCauser, bool bIgnoreShields, bool bIgnoreHealthArmor,
bool bIgnoreShieldArmor)
{
CustomOnTakeAnyDamage(Damage, Force, EventInstigator, DamageCauser);
if (GetHealthComponent())
return GetHealthComponent()->TakeDamage(Damage, Force, HitLocation, HitBoneName, EventInstigator, DamageCauser, false, false, false);
return Damage;
}