I have a question. I am using this overlap to cause damage to a certain character. But I don’t want the overlap to pass through walls. But if it passes through wall how can I prevent damage to the character on the other side of the wall? I am not sure if I should use an overlap or a sweepmultibychannel. Even when I used the sweep the sweep would pass through walls even though the trace collision channel was set to block by the wall that was on the other side of the character I am trying to hit. What would be the best way to make a grenade overlap or raycast effectively and realistically. I just see games where there is a grenade thrown into a room and the room blocks the grenades overlap or raycast. How could I replicate that in the most effective way possible
//This function is called by a timer.
void AGrenade::Explode()
{
TArray<AActor*> OverlappingActors;
//This is the sphere component.
DamageSphere->GetOverlappingActors(OverlappingActors);
//Looping through all of the actors that are inside the overlap for results.
for (AActor* Actors : OverlappingActors)
{
//This enemy is affected through walls.
if (AEnemy* Enemy = Cast<AEnemy>(Actors))
{
Enemy->DecrementHealth(WeaponDamage);
UE_LOG(LogTemp, Warning, TEXT("OverlappingActors: %d"), OverlappingActors.Num());
Enemy->GetMesh()->AddRadialImpulse(Enemy->GetActorLocation(),1000.0f, 2000.0f, ERadialImpulseFalloff::RIF_Linear, true);
}
}
}
}
In general, you will use an overlap to find possible objects to damage, and then you will sweep to see whether the damage is blocked or not.
In Blueprint, we have the convenient gameplay static function “Apply Radial Damage” (and “… with Falloff”) which claims to only affect objects that block visible queries, but it doesn’t do the ray trace for you, so you unfortunately can’t use it. But you can look up the source, and compare to your own, and then add the ray cast before the damage is actually applied.
Look for bool UGameplayStatics::ApplyRadialDamageWithFalloff in GameplayStatics.cpp
A single ray may be annoying when enemies know to hide between very thin objects, which you can make better by casting more rays (3 or 5, typically) slightly perturbed to the side from the center of the explosion, towads a similarly slightly perturbed center of damaged object. Similarly, to avoid the “chest high wall” problem, casting rays slightly higher and slightly lower may be helpful, all depending on how accurate you want to be versus how many rays you can afford to cast when something explodes.
Could you show an example in code on what to do in this instance? The overlap passes through walls regardless but how could I then block for damage. If I use collision filtering the overlap gets block but so does the object’s movement does too.
ApplyRadialDamageWithFalloff actually does the raycast by calling ComponentIsDamageableFrom for all the overlaps gathered in the first step. Unless you provide an invalid DamagePreventionChannel. It uses the Origin of the RadialDamage as Start and the Origin of the Component’s Bounds as the End. So it may still run into the problems you’ve described.
The problem is even with collision filtering if I use a overlap with a sweep. The overlap gets blocked but the projectile movement’s does too. That is because the damage sphere is attached to the projectile.
When you say casting rays are you referring to singlelinetracebychannels or multilinetracebychannels. Or multisweepbychannel or singlesweepbychannel?
Oh, you’re right! I was looking for the Visibility channel, called out in the documentation, but that’s just the DamagePreventionChannel argument, which might default to visiblity but could be changed.
Looks like it does a single raycast, using LineTraceSingleByChannel(), which is good enough in 90% of cases.
I swear, this engine solves almost every problem, the challenge is finding the actual place and method by which it does it
All four of those are options. The sphere traces will get blocked more easily by thin blocking geometry. Which one you choose, depends on your particular needs.
It is just when I use a singlesweepbychannel the walls do not block the trace I throw the grenade the timer goes off the sweep happens and the trace does not get blocked by the custom collision channel that I have in place in order to block the sweep. With the singlelinetraceby channel would I just use multiple linetraces pointing out in different directions or would I just try to get the actor location of the enemy? I need specifics I am a type of person that needs specifics not general ideas.
Would the singlesweepbychannel work in this case I have tried it but it does not become blocked by the thin geometry I have in place blocking the collision channel I don’t know if it is a bug or what. It is weird.
I am going to apply single line trace by channels in all directions because the sweeps hit through walls and the overlaps do too. I am going to put a ton of single line traces because if an enemy is behind cover the linetrace will hit the cover if not the linetrace will hit the enemy. This sounds like a really brute forced method but I will stand by it cause it might just work. The linetraces will act as shrapnel.
Typically, you do it the other way around: get the center of the explosion, get the center (or head) of the target-that-overlapped, and then run that line trace. If the trace is blocked, no damage, else damage.
GamplayStatics::ApplyRadialDamageWithFalloff() does approximately this, although it tests to the center of the damaged component (typically, the character capsule) rather than the “head” position, if that’s what you want.
So, yes, the overlap finds a bunch of things in cover. That’s fine – that’s why you then do the second phase of ray casts, before you apply damage. As I suggested above, read through ApplyRadialDamageWithFalloff() for inspiration. One way to find that function, if you don’t know how, is to install “Void Tools Everything for Windows” (google it, it’s free, and very legitimate, run it as an admin service,) and then open up that window, type in “GameplayStatics.cpp,” and up comes the source file for the engine with that name. Double-click it to open it in Visual Studio.
Another way to find that implementation is to add a dummy/empty call to it in some blueprint (like your player controller,) and double-click the blueprint node, if the integration with Visual Studio is working right (which it often does,) it will jump straight to the function implementation.
So what I do is check to see if the enemy is inside of the overlap then run a line trace from the grenade to the enemy using a cast to check to see if the enemy is hit.
This is what I have so far I just am trying to have the raycast hit the enemy chest level. I think this is about right. I think I managed to get a blocking hit here!