I want to be able to modify any character stat (health, speed, wisdom, strength, etc.)
I have the following function which works fine for health.
float AFPSCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
{
// If health is already gone
if (Health <= 0.f)
{
UE_LOG(LogTemp, Warning, TEXT("Health is already gone"));
return 0.f;
}
// Call the base class - this will tell us how much damage to apply
const float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
if (ActualDamage > 0.f)
{
// Reduce health
Health -= ActualDamage;
// Handle death
if (Health <= 0)
{
Die(ActualDamage, DamageEvent, EventInstigator, DamageCauser);
}
}
return ActualDamage;
}
I would like to modify this to work for any character attribute.
I have tried a couple things.
My first approach was to create a new function that wasn’t override and have this one call the Super::TakeDamage. Like so. However, for radial damage ApplyRadialDamage calls TakeDamage under the covers. Therefore, I would still need an overriden TakeDamage to control what happens there. Since TakeDamage is overriden I can’t pass additional parameters, such as an enum for the attribute to modify.
void AFPSCharacter::InflictDamage(EFPSStat StatToDamage, float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)
{
// If this was a radial damage event
if (DamageEvent.StaticStruct() == FRadialDamageEvent::StaticStruct())
{
// ApplyRadialDamage here
}
else
{
// Call the base class TakeDamage
const float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
}
switch (StatToDamage)
{
case EFPSStat::Health:
CharacterStats.Health -= ActualDamage;
}
}
So I scrapped that approach.
My next idea was to override TakeDamage and then piggyback on it’s existing parameters. One of those parameters is a FDamageEvent. So I would create a custom UDamageType and add the attribute to modify enum there. However, the issue with that is FDamageEvent’s constructor takes a UClass parameter like so.
FDamageEvent
(
TSubclassOf< class UDamageType > InDamageTypeClass
)
Therefore, I can’t specify an attribute enum per TakeDamage call. Since you can only set defaults on UClass and you can’t actually change any properties on them.
So, the only idea I had is to create a ton of UDamageType classes. It’s really ugly and I would rather not. And even that isn’t realistic because what if I want there to be a damage type that sets the player on fire and also lower there wisdom or something?
So does anyone have any ideas?