Finding the Closest Actor to a Given Vector and/or Rotation

I have the need for a bit of code that will find the closest actor to a given vector or rotation. Basically, I want to be able to look in a direction and the actor closest to that direction is chosen even if the chosen actor is in the opposite direction.

I have a reference to all the actors that are capable of being targeted, I just need a way to pick the one closest to the given vector/rotation.

You can do this a few ways. One of them would to be use a sort of pawn sense. What I would look into would be line traces. You’d basically shoot the trace to each of the actors from the player and get the dot product to see the angle between the player’s forward vector and the direction of the trace and see if it’s some value between 1 and 0. But if it’s 0, that means the lines are perpendicular, so maybe choose a different value like 0.45 as your lower bound of the dot product’s result for a valid “look at”. Let me know if that works or if you need any clarification!

Perhaps one of these, or combination of would do the trick?

Didn’t feel like setting up an actual example, since I believe you have pretty much all you need. You can get a vector location from a references you already have. Let me know if you need more an example and I will put something together. :sloth:

This solution was terrifyingly easy to implement, but how would i go about sorting the values to pick out the one closest to zero without excluding negative numbers using the ABS node, resulting in a target from behind getting chosen when their ABS value is smaller.

If you’re worried about the distance between the player and a valid actor, you can write a function that returns that actor of the shortest distance away. You just loop through those valid actors and check their distances and keep track of the smallest distance and the actor that distance is paired with and then return the actor that’s closest.

I’m not too concerned about the distance between the player and the intended target, but when using ABS to compare the values, I’m running into an issue where I will look just to the side of the intended target and the chosen target ends up being behind me instead.

I think I have an idea of what’s going on but could you show me the code segment where you’re doing your calculations

Sure thing.

Here is the code segment that’s running the math for the line traces:

Here is the code segment that’s running the math for finding the closest to zero:

Ok I see and just for some more clarification, I drew up an example of what we’re looking for. I have the green circle is the player and the direction they are facing. We want the valid candidates to be only what’s in front of the player (in the blue box) and the selected actor to be the closest of those candidates (in the purple box)?

Let me know if that checks out

the valid candidates for selection can be any of the possible targets, whether they are behind the player or to their side, but the target we want is the target closest to their direction. If the player isn’t looking directly at or next to a target, the next valid target is chosen.

You keep saying direction, but then mentioning that the rotation doesnt matter.

Thats because what you acrually want is the location.
You want a look at - to the actor to be chosen.

Alternatively, if you socathoa it, then something like Dot will give you the + and - you need to determine everything. But, you have to base your math on the result of the main actor forward vecor and the other actor Locations (not rotations).

There is technically no need to line trace, or anything, except for math and knowing your trig.
But… you can’t relay on a loop for this to work either since unreal engine and loops dont really jive.

I would suggest this as a pseudocode/setup:

Add a collider to the main acotor (a cylinder) in the size you want to scan objects for.
Add an event to the actor. Get all actors (of class) within the collision of the cylinder (use sweep).

Check how many actors there are - if more than 10, you have to make something that is async or not on the game thread or the loop will probably fail.

If less than, you do the maths and store the result to a soft variable of type actor (so you store a ref to the closest actor).

As the loop progresses, only the closest actor is stored up for you - and you can further code up ways to manipulate “who” is closest, or if they are facing behind or in front of the actor’s location, etc.

The limitations to this are the number of actors involved.

But you can also restrict that by making your collider a different shape or size, or chaning the collision channels for the actors so as to only have some respond.

You can’t have the loop do crazy maths though - like look at is altready expensive as it is, so go with the sinpler things whenever possible.

The real reason blueprint loops fail is that it’s thread blocking, and therefore a large delay will cause the engine to claim the loop is infinite…

1 Like

While I do know about the collider method, it doesn’t quite work for the scenario I need. What I want is the ball to bounce toward a target you can control without having to look directly at the target 100% of the time.

Yes, you’re right, I should specify that I want the player’s forward vector to control what target you want the ball to go after. Rotation entirely matters here, but the location of the other targets doesn’t. The rotation of the player should control what target is chosen next regardless of the location.

For example, I want to target someone sitting between two other targets, I just need to look directly at them and it will function.

The current iteration gives these results, with certain scenarios resulting in targets being chosen that aren’t even on the screen simply because the ABS of the DOT product ended up being smaller than the ABS Dot product of the target I was looking at.

I apologize for confusion that was caused.

As for the amount of targets, there will only ever be 10 at any given time with the amount being reduced as the game progresses, however, they can be anywhere in the map.

The ball starts in the center, picks its first target, and uses the Floating Pawn Movement component to add an input to the current forward vector while using a RInterp To node to control it’s movement to direction of the target slowly increasing it’s Interp Speed to prevent going in circles when positioned just right.

The player can use their own forward vector to control what target is chosen next by looking in their direction, with the location not mattering, the target of the ball will change to whatever target is closest.

sorry I know it’s a bunch of back and forth. I just want to make sure I’m helping solve the correct problem. Could you do a super simple sketch or a few showing the different scenarios with a brief description just so I can understand what you’re going for just because I think words can only go so far. (we’re gonna get you through this!) :slightly_smiling_face: