Download

Casting UDamageType

Hello everyone,

I have some trouble to correctly use damage system with damage type in C++.
I create a subclass BaseDamage derived from UDamageType and an interface ProcessDamage.

Interface ProcessDamage :
[SPOILER]



UINTERFACE(MinimalAPI)
class UProcessDamage_Interface : public UInterface
{
    GENERATED_BODY()
};


class BRAWLERS_3D_API IProcessDamage_Interface
{
    GENERATED_BODY()

public:

    UFUNCTION()
    virtual float ProcessDamage(AActor* Target, AActor* Causer, float Damage = 0.f) const;
};


[/SPOILER]

BaseDamage :
[SPOILER]



UCLASS()
class BRAWLERS_3D_API UBaseDamage : public UDamageType, public IProcessDamage_Interface
{
    GENERATED_BODY()

public:

    UBaseDamage() = default;

    UFUNCTION()
    virtual float ProcessDamage(AActor* Target, AActor* Causer, float Damage = 0.f) const override;
};


[/SPOILER]

When I use the function ApplyRadialDamage for a fireball for exemple, I put my subclass in parametters:
[SPOILER]



void AFireball::OnHit(    UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
    UGameplayStatics::ApplyRadialDamage(
        GetWorld(),
        Damage,
        Hit.Location,
        DamageRange * ExplosionScale,
**TSubclassOf<UBaseDamage>(),**
        TArray<AActor*>(),
        this,
        (AController*)GetOwner(),
        true,
        ECC_Visibility);

    Destroy();
}


[/SPOILER]

For the damage system, I use the delegate OnTakeAnyDamage.
[SPOILER]



void ABaseCharacter::BeginPlay()
{
    Super::BeginPlay();
    OnTakeAnyDamage.AddDynamic(this, &ABaseCharacter::ChraracterTakeDamage);
}


[/SPOILER]

But in my class character when in try to use and cast UDamageType to my BaseDamage class it fails…
After the cast my variable baseDamage are nullptr.
[SPOILER]



void ABaseCharacter::ChraracterTakeDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
{
**const UBaseDamage* baseDamage = Cast<UBaseDamage>(DamageType);**

    if (baseDamage == nullptr)
    {
        HP -= Damage;
        GEngine->AddOnScreenDebugMessage(-1, 4.5f, FColor::Orange, "damageType is null");
     }
     else
         HP -= baseDamage->ProcessDamage(DamagedActor, DamageCauser, Damage);

     if (HP <= 0.0f)
         GEngine->AddOnScreenDebugMessage(-1, 4.5f, FColor::Purple, "IsDead");
}


[/SPOILER]

I try another function to make the damage system with the function TakeDamage() from AActor class but the same problem…

Thank you in advance for your help!

You’re passing **TSubclassOf<UBaseDamage>() **into ApplyRadialDamage, thats an empty (null) class pointer.

You should be passing UBaseDamage::StaticClass()

It works perfectly !!!
Thank you very much!