Best way to deal with multi sphere trace line of sight?

As it stands I do a multi-sphere trace, which could easily hit say 50 AI. I then do a line trace for each hit to make sure nothing blocking is in the way. This ensures line of sight for my AOE attacks so they’re not hitting through walls for example.

My chain lightning ability chains to the nearest target and to do this it multi-sphere traces, checks line of sight, picks closest target of the remaining that are in line of sight, then chains again. This ends up being 100+ line traces once all said and done due to line of sight checks.

Is this a practical approach? I’m not seeing any performance issues in profiling, but seams crazy to do so many traces to check for line of sight. Is there a better way?

Optimized it further. When building my array of closest hits from my distance map I do my line of sight check to determine if they should be added to my closest hits array. Normally I’m only getting the first closest hit or maybe first 3 closest hits. Result is on average 1 line trace for line of sight instead of 50. Huge difference. Still not totally sure if doing a line trace after a sphere trace is the standard practice though.

1 Like

If you want to check line of sight, there’s really not any other option than to do traces for each actor in the array index. You can set AOE caps like you’ve mentioned, and just conduct no further traces after the index reaches your cap.

If you’re not seeing problems during profiling, the next best thing would be to test it on lower-end hardware. Also, take a look at some of the builds guys are making in Path of Exile; lots and lots of traces and overlap events getting triggered in the span of a few frames. It may be nothing to worry about.

Does firing a projectile that applies radial damage not do the job? Radial damage doesn’t go through walls does it?

I don’t know whether it would be any simpler in terms of calculation, but may be simpler to implement.

So far doesn’t seam like there’s any issues. Tested my aura ability whacking 50 enemies at once and the traces are barely even a blip in unreal insights so I guess it’s fine, lol.

I don’t use the built in damage functions. They’re too limited. I need to pass far more data along than the internal functions allow for.

Just checked documentation as well. The Apply Radial Damage is just doing exactly what I’m doing. Does line traces against the Visibility channel so it’s probably not any more performant. So since the official function is doing it I guess this is the way to do it.

I suspected. So that tells us what you’re doing is probably not a big deal. Feels like it because you get to see all the debugs.

Some alternatives that could help:

  • Try a cone shape collision to get overlapping actors in angle in front of player rather than multi trace. Removes the need to tick if managed on begin/end overlaps.
  • Then trace each: tested tracing for static objects; if no hit then there is line of sight:

From the sort function of your other post Get closest hit to origin in a multi sphere trace? - #10 by Krileon :

  • IMO might be better to just have 2 separate arrays over a map. Having 2 separate arrays allows to sort without duplicating. Then access closest from index 0->.

Haven’t really compared, just thought it was worth the debate.

I don’t need a cone trace, but a sphere trace with line of sight. If I needed a cone trace I’d still do a sphere trace and use vector math to filter out any hits that aren’t within my cone. I actually have a post about this below with the vector math provided.

I do not recommend trying to do custom traces by attaching collision shapes to actors. They’ve to update their transform along with the actor. That’d be a lot slower than doing a sphere trace. The sphere trace itself is incredibly fast. Even if it hits 1000 it’s fine. It’s just itinerating over that 1000 for example that could be slow, but that’s mostly a BP problem. CPP can deal with large loops fine.

I don’t see why it’d matter to be honest. You still need to push the sorted results into an array to be returned.