How to apply radial damage to all actors in the area?

Hello,

This might be simple, but I’m stuck with this some days :frowning:

I’m working on a 3D side scroller game, and I have some abilities (like misiles, grenades, invisibility areas…) which deal damage and some custom behaviour to the surrounding players. The problem is that if i got more than 2 players in the same plane, the applyRadialDamage only deals damage to the first player, and not to the one who is behind him. I try to change the ECC, but still don’t works.

UGameplayStatics::ApplyRadialDamage(GetWorld(), 10, GetActorLocation(), 500.0f, UD_Invisibility::StaticClass(), TArray<AActor*>(), this, (AController*)GetOwner(), true, ECC_Visibility);

Thx in advance :slight_smile:

Hello, Davixe

In this situation, you can do the following:

  1. Iterate amongst all actors of particular class.

  2. Check each actor for distance and apply damage for the ones that are close enough.

Your code will look something like this:

for ( TActorIterator<ACustomCharacter> it(GetWorld()); it; ++it )
 {
     float Distance = GetDistanceTo(*it);
 
     if (Distance <= DamageRadius)
     {
         UGameplayStatics::ApplyDamage(*it, DamageAmount, 
         GetInstigatorController(), this, UDamageType::StaticClass());
     }
 }

This should do it.

If you like to learn more about iterators in Unreal Engine 4, please go here:

Hope this helped!
Good luck!

Although the solution proposed by would work, I think it will come with bugs like damaging objects behind hit-blocking collisions like walls.

I believe the proper way to achieve this is by using the DamagePreventionChannel argument in ApplyRadialDamage. This collision channel, which defaults to Visibility in the function signature, will block all damage between the explosion point and potential objects.

An easy way to have the damage go “through” the players in your example is to set the collision reaction to the visibility channel to ignore, or to create a new custom DamagePrevention channel in your game and flag your physics objects appropriately.

Cheers,

Phil

Yep, that was the kind of answer I was looking for, because ApplyRadialDamage should take into account that kind of behaviour. But I got the following problem ( or maybe I just misunderstood the DamagePreventionChannel ).

I use ECollisionChannel::ECC_WorldStatic on the DamagePreventionChannel and I expect to damage all players inside the given radius except all of those who are behind any wall with WorldStatic collision. But with this, my pawns are not recieving damage at all, but if I use ECollisionChannel::ECC_Pawn (or ECC_MAX) the damage are applied to all my pawns inside the radius correctly (no matter if they are behind a wall or not)

I thought the DamagePreventionChannel are used to preventing damage to be applied if an object with that collision chanel is between the origin of the radius and the victim :confused:

Look in GamePlayStatics.cpp, function ComponentIsDamageableFrom. There’s a LogDamage that you could enable via console command (“log damage on” will do I think, but I’m unsure) to enable debugging, and there’s also a debugdraw that you could uncomment to help you understand what’s going on. I think you understood DamagePreventionChannel right, there must be something that’s flagged WorldStatic that blocks damage everywhere, you just have to figure out what.

I did more test on that function, and I think that ApplyRadialDamage only works for TraceResponses (ECC_Visibility & ECC_Camera), So it doesn’t work well with the rest of collision chanels (on the ComponentIsDamageableFrom it uses LineTraceSingleByChannel and not LineTraceSingleByObjectType).

My solution was create a custom trace response for the radial damage and set them on ignore on my pawns and block on my walls)

Thx for your help PhilPix :slight_smile:

I had the same issue. I had no idea what went wrong. I fixed the issue by fixing my pawns’/characters’ collision. I had custom collision on, and when I flipped the collision from custom collision to “pawn” preset, the problem got fixed.

This issue only happened for Apply Radial Damage with Falloff. I’m not exactly sure why it worked fine for Apply Radial Damage (no falloff), but I think it has to do with the Damage Prevention Channel. From my limited understanding, the damage prevention channel prevents damage from hitting actors if whatever you specify in the Damage Prevention Channel gets in between the origin and the actor you want to damage.

In my case, I had custom collision preset on, and I set visibility to block. But the pawn preset sets it to ignore I believe. So when I set the preset back to pawn, visibility no longer blocked the damage.

I fixed a similar issue by adding the actor that initiates the radial damage to the array of ignored actors.

The best is to replicate ApplyRadialDamage behavior, but without Hit Check.