I have made a system that makes an NPC animal flee from threat actors and it works well, the issue is when there are multiple, I want the NPC to calculate the “safest” route to get away from them, using the distance between each threat but I can’t get it to work.
I have tried merging vectors, adding them and normalizing in about every configuration I can think of. I am in over my head a bit but I feel so close to the answer but can’t figure it out.
Think you don’t want to have the furthest point right? That one is quite easy I can show,
I think you want to have “best possible direction to escape”, (correct me if I am understanding it wrong)
Make array out of this and add them up with a loop, is your escape vector.
However, this should be calculated individually per fleeing NPC, not once as a shared vector for a whole group. Otherwise, in edge cases, one of them can get a bad direction and run toward a threat instead of away from it.
If multiple threats at the same time, one approach is to simply average them get center,
or again we can weight the threats get a more meaningfull one,
or if you want truly a path, then you can spawn some navmesh modifiers and pathfind which is more heavier but more realistic end results would be.
The blueprint works for single threats, but when a second gets involved the NPC just freezes in place, my ideal result is that the NPC gets both vectors and heads in a direction away from both, like to the side.
You mentioned averaging all the results and/or weighting the threats, which would be better for what I am trying to go for? The NPC will be in very close proximity to multiple threats and in a way scurry between them to get away.
Sorry for the questions, it was quite tough getting it to work and I am a bit uncertain of the approach I should take, haven’t had this much trouble in the project yet and would love to keep my momentum!
Thank you for your time, and thank you for the welcome and help again too! Have a wonderful night.
Moving away from average location could work. Another (possibly insane) idea would be to attach a large non-solid collision box to predators, make it affect nav data and assign a nav modifier class to it which makes a path thru it super expensive so ai would avoid it naturally.
There are couple of honorable mentions above for solutions space however generally averaging solution that I mentioned should work.
So couple of things in your scripts just to be sure.
This is a function but I see locations array is global for class. So maybe clearing it before function runs can be a good idea.
Your logic can work, but with two threats the flee vectors can cancel each other out. That is probably why it freezes.If one threat is on left and one is on right, the summed vector becomes nearly zero, so the final MoveTo location is basically the NPC’s current location.So after adding all flee vectors, check AvoidSum length. If it is very small, use a fallback direction, for example a perpendicular direction, random reachable point, or EQS query.
If I see it correctly, in the end you are adding Sum to NPCLoc, which is correct if the sum is multiplied by a DistanceFactor like 100, since it would be quite small value even with additions. The Sum gives you an escape vector, either for steering or, as mentioned, to derive a point outside somewhere with multiplication by distance.
Thank you for the reply, as for the EQS I am already using one to fire of the calculation, the average vector looks in
Hello and thank you for the response!
For the EQS, it is already implemented in that way for the blackboard using a function inside the NPC’s blueprint that gets called to, as all other calculations for other movement and reactions are located there.
As for the get actor array average location, it looks good apart from being able to implement weighting in the final vector, do correct me if I am wrong, (which may be very likely), but I don’t see a way of implementing a weighting system as Grimnir suggested. Not without looping through like I have anyways to get the extra information like distance.
The final goal is to have outward factors like the type of threat influence the vector, but simply for now in my demo distance is more than enough, just a case of getting it to work.
Thank you again for the response and have a lovely day. : )
Get Actor Array Average Location is good for simple unweighted center, but if you want distance weighting now and threat type/intensity later, then you still need some kind of loop or custom scoring.
Then after loop, normalize AvoidSum, multiply by FleeDistance, and add it to AI Loc.
Since the question a bit evolved from furthest point from multiple actors to a long term ThreatSystem if you want threat intensity, threat type, fire, environmental danger etc. then I think it becomes more like potential field / influence map problem. That’s another level of problem especially if you are dealing with an openworld problem. That time each source should contribute then AI samples nearby directions or candidate points, combines threat values from all nearby sources, and moves toward lower-threat area.
So it becomes less “run away from this actor” and more “move toward safer value in surrounding space.” I have experimented with a similar approach a while ago over here , using both baked fields and runtime changes on top of sampling for thermal sources.
in the long term it might be better to make a grid, almost like a pathing grid that way you can store threat but also things like cover and other points of interest.
Try using a weighted repulsion vector sum the vectors away from each threat, giving closer threats a higher weight. If that still isn’t enough, score several escape directions and pick the one that maximizes distance from all threats.