UGameplayStatics::ApplyRadialDamage

Hello. Im trying to apply radial damage but its no doing any damage. Everything working in the function in which im using radial damage. Just so you know, i do have take any damage in my player class and point damage is already working but now i’ve included radial damage and its not working(no damage).

I tried exact same thing that you suggested and still nothing no UE_LOG. So here is what exactly im doing. I have an actor component which im using as a health cmoponent.
This is the actor component code:

USHealthComponent::USHealthComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;

	DefaultHealth = 100;
	SetIsReplicated(true);
}


// Called when the game starts
void USHealthComponent::BeginPlay()
{
	Super::BeginPlay();

	if (GetOwnerRole() == ROLE_Authority)
	{
		AActor* MyOwner = GetOwner();
		if (MyOwner)
		{
			MyOwner->OnTakeAnyDamage.AddDynamic(this, &USHealthComponent::HandleTakeAnyDamage);
		}
	}
	
	Health = DefaultHealth;
}

void USHealthComponent::HandleTakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
{
	if (Damage <= 0.0f)
	{
		return;
	}
	Health = FMath::Clamp(Health - Damage, 0.0f, DefaultHealth);
	UE_LOG(LogTemp, Warning, TEXT("Health is %s"), *FString::SanitizeFloat(Health))

	OnHealthChanged.Broadcast(this, Health, Damage, DamageType, InstigatedBy, DamageCauser);
}

As you can see i also also have DECLARE_DYNAMIC_MULTICAST_DELEGATE in actor component which has 2 additional parameters. Now in my Player class im binding that broadcast in BeginPlay().
Here is the player class code of bind function:

void ASCharacter::OnHealthChanged(USHealthComponent* OwningHealthComp, float Health, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
{
	if (Health <= 0.0f && !bDied)
	{
		bDied = true;
		GetMovementComponent()->StopMovementImmediately();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);

		DetachFromControllerPendingDestroy();

		SetLifeSpan(10.0f);
	}
}

This is the code im using and point damage does work with this but not radial. As i mentioned in the start, i tried adding OnTakeRadialDamage in Player class separately but still not receiving.

Hi GameGod786,

[UPDATE - 17/03/19]

Here is a minimal demo of what you’re trying to achieve. I have created two classes:

  • ARadialDamageActor : The actor that ‘explodes’ and deals radial damages.
  • ADamageableActor : The actor that receives the damage.

RadialDamageActor.h

  UCLASS()
class MYPROJECTCPP_API ARadialDamageActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ARadialDamageActor(const FObjectInitializer& ObjectInitializer);

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UStaticMeshComponent * StaticMeshComponent;

public:	
	void Explode();
	
};

RadialDamageActor.cpp

// Sets default values
ARadialDamageActor::ARadialDamageActor(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	StaticMeshComponent = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Static Mesh Component"));
	RootComponent = StaticMeshComponent;
}

// Called when the game starts or when spawned
void ARadialDamageActor::BeginPlay()
{
	Super::BeginPlay();
	
	Explode();
}

void ARadialDamageActor::Explode()
{
	UE_LOG(LogTemp, Warning, TEXT("ARadialDamageActor::Explode"));

	TArray<AActor*> IgnoredActors;

	UGameplayStatics::ApplyRadialDamage(this, 50.0f, GetActorLocation(), 500.0f, nullptr, IgnoredActors, this, GetInstigatorController(), true);
}

DamageableActor.h

UCLASS()
class MYPROJECTCPP_API ADamageableActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ADamageableActor(const FObjectInitializer& ObjectInitializer);

protected:

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UStaticMeshComponent * StaticMeshComponent;

	UFUNCTION()
	void TakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser);

	UFUNCTION()
	void TakeRadialDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, FVector Origin, FHitResult HitInfo, class AController* InstigatedBy, AActor* DamageCauser);
};

DamageableActor.cpp

// Sets default values
ADamageableActor::ADamageableActor(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	StaticMeshComponent = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Static Mesh Component"));
	RootComponent = StaticMeshComponent;

	// Bind functions to OnTakeAnyDamage and OnTakeRadialDamage delegates
	OnTakeAnyDamage.AddDynamic(this, &ADamageableActor::TakeAnyDamage);
	OnTakeRadialDamage.AddDynamic(this, &ADamageableActor::TakeRadialDamage);
}

void ADamageableActor::TakeAnyDamage(AActor * DamagedActor, float Damage, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser)
{
	UE_LOG(LogTemp, Warning, TEXT("ADamageableActor::TakeAnyDamage - %f"), Damage);
}

void ADamageableActor::TakeRadialDamage(AActor * DamagedActor, float Damage, const UDamageType * DamageType, FVector Origin, FHitResult HitInfo, AController * InstigatedBy, AActor * DamageCauser)
{
	UE_LOG(LogTemp, Warning, TEXT("ADamageableActor::TakeRadialDamage - %f"), Damage);
}

In my demo, when I press play, both ‘TakeRadialDamage’ and ‘TakeRadialDamage’ are being called once.

Please, tell me if that doesn’t help.

Cheers.

Thanks for reply. I mentioned above that i do have OnTakeAnyDamage on my player class. I also have weapon class and i have point damage using line trace on weapon and its working but then i made a bot which is suppose to explode when near the player. So in one function i have exploding code like particles sound etc and in there i also have ApplyRadialDamage. Everything in that function works except radial damage. Hope i explained everything.

Hi, can you update your original post and show the part where you bind a function to the ‘OnTakeAnyDamage’ delegate as well as the function itself?

Hi GameGod786, I have updated my answer with a minimal demo.

So OnTakeAnyDamage does not receive radial damage? Is this the reason i have to use both OnTakeAnyDamage and OnTakeRadialDamage? Because i thought i could just do it with only OnTakeAnyDamage.

Hey, Please could you update your original post instead of posting new answers. The main difference I see with the demo code I provided is that you bind ‘HandleTakeAnyDamage’ in the BeginPlay of your component while I do it inside the constructor of the actor. So can you try to bind your function to ‘OnTakeAnyDamage’ delegate inside your component’s constructor?

Im sorry. I dont mean to post answers everytime. im just not familiar with this. Anyway i tried moving HandleTakeAnyDamage in the constructor. Im not getting any compile error but its like this function doesnt exist(not called when hit). I also tried moving my bot’s and player’s OnHealthChanged bind function from beginplay to constructor and same thing happened, no error but functions are not called. Seems like they only wanna work in beginplay.

Hello. I tried moving HandleTakeAnyDamage in contructor as you suggested. I dont get any compile error but its like the function doesnt exist(Not called when hit). I also tried moving my bot’s and player’s bind function(OnHealthChanged) from beginplay to constructor, same thing happened, no error but function are not getting called(by the way im using UFUNCTION() on every bind function). In my code it seems like bind function only wanna work in beginplay and not in constructor.

Two more things to check : are the exploding actor and the damageable actor close enough (with a distance < to the damage radius set in ApplyRadialDamage)? And is the collision response to the visibility channel of your damageable actor set to block? If that doesn’t help, I will need to see your project to further assist you.

Yes the distance is less then the radious because i tested it with DrawDebugSphere on bot’s location. Player Capsule has everything set to block except visibility and camera. Player Mesh set to block all. Also there is one problem. Im telling because it might be connected to my damage problem. So im using a sphere component on my bot which triggers overlap event.

SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
	SphereComp->SetSphereRadius(200);
	SphereComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	SphereComp->SetCollisionResponseToAllChannels(ECR_Ignore);
	SphereComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
	SphereComp->SetupAttachment(RootComponent);

Now the problem i was facing here is that the OnComponentBeginOverlap was not firing when it overlaps with the pawn but i clearly set it to do so. After messing around i found out that i have to set everything on sphereComp to ignore except worldstatic(Overlaps) which makes no sense to me because i think pawn should be the one overlaping not worldstatic. So i have no idea why worldstatic has to be the one overlaping.