Efficient way to sort through array to find closest by priority?

Say you have an array of actors. They each have a type with is prioritized. For example, orange is #1, apple is #2, pear is #3.

So if no oranges are present but apple is and pear is, the apple is targeted first.

Among those priority targets, we want to select which one is closest to the player.

It seems that there is no way to do this operation other than by iterating through the array completely one time to find all priority targets, and then consolidating these to a new array, and then iterate through the priority target array to find the closest actor.

Is that right? Is there no more efficient way to do it?

1 Like

Hey @BIGTIMEMASTER!

As far as I’m aware, yes, that would be the most efficient way- though, if you’re looking upwards of thousands of possible targets I’d change it. At that point, a SphereTraceForObjects with an output of the array of targetables would be recommended to create the initial array, I’d say.

I assume you’re meaning to get distance between the player and each one of the prioritized actors on the fly? I mean that’s not extremely heavy. Again- provided the number of targets isn’t high.

2 Likes

There are dedicated plugins around that are optimized to query large worlds with loads of actors (TheJamsh used to publish one iirc). However, if this is all being done in C++ anyway, maybe it doesn’t matter. But if this is BP, then how is the priority decided (known)? If only each actor knows, then thinking maybe an interface call to ‘Get-Priority’ to avoid casts might be best. Along with Get-Squared-Distance-To (especially if there’s 1000’s or 10000’s of actors). :wink:

As suggested doing a trace first would be wise (to limit the size of the array). The problem with that though is, what if all the actors found in the trace are #2 priority, but there’s an actor with #1 priority that lies just outside the trace range… Also, if you have to use one of the Get-All-Actors type nodes to create a master actor list, try to run that part on an infrequent timer. :thinking:

Last thing… If the actor + priority are known (stored in struct / 2 arrays), there are free BP plugins that allow various types of sorting, which would help avoid trawling the entire array. :stuck_out_tongue_winking_eye:

2 Likes

I am getting the array from GetOverlappingActors from a sphere collision. So the total amount may be around a dozen at max.

But I think I realized that sorting a second local array is not needed. Because we can check actors type and distance in the first pass, and just replace a local variable if new actor is closer than previous (and of the right type).

The difference there might be neglible but I think it is the reason why in back of my mind I felt like I was doing an unnecessary step.

2 Likes

Thinks for the tips!

In this case I am only sorting at max like a dozen actors or so. I am getting this setup in BP but I can move to c++ if needed.

As for the sorting by distance, I was using the Low Entry Standard library which helps with that. It does the sorting in c++ I believe but you have to define a predicate function in blueprint to give it whatever sorting parameters that you want.

I doubt performance is going to be an issue for me since I am only sorting those nearest to the player which have been captured by a sphere collision (and this is only tracing for a specific channel of objects), however it’s still good to try and do things in an efficient way I think so if things expand or change I’ll look into some of these more advanced tools.

1 Like

Adding the blueprint code here just in case it is helpful for anyone:




Summary is that we only loop through those actors which have been filtered by object collision type. Then via a component which holds an enum, we check type and if the type is of higher priority, we make that the new “chosen” target.
If new target is of same priority, then check distance and the closer one wins.

I run this on a timer which updates every quarter second. In a slower paced game you could do it less frequently.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.