This is my implementation of auto targeting for FPS:
for (float k = -0.1f; k < 0.2f; k += 0.1f)
for (float j = -0.1f; j < 0.2f; j += 0.1f){
new Quaternion().fromAngleAxis(j, Vector3f.UNIT_Y).fromAngleAxis(k, Vector3f.UNIT_X).mult(cam.getDirection(),rayDir);
CollisionResults results = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), rayDir);
shootables.collideWith(ray, results);
//...
}
So I basically cast 9 rays for simulating an “aiming frustum”, then I check collisions. It works, but I wonder if there is a better approach…
If you’re not dealing with too many targets at once, it could be an idea to compare angles between the direction of the player’s shot and the angle between a checked target and the player.
Rundown: The player shoots the gun, it doesn’t hit any target. Next we cycle through the possible targets (with some type of smart geometric indexing we could filter to only check in plausible areas, not behind the player etc.) Of all the potential targets, we calculate an angle between them and the player. If one or more of the targets are within the given angle of error, we select the closest one (by angle first, then distance second)
Here, I’ve scribbled down my idea onto a 2D overview
Note however, this is entirely theoretical, I have not done something like this before.
For auto-targeting you should just get a list of close-by enemies and then do the computation from there. Almost every game should have an easy way of getting all entities within a rectangle / circle / cone which is independent of the scene graph, to be used for purposes such as this. Once you have the list of potential entities you can compare angles and all of that.
As mentioned in the other thread, ray casting is slow because it performs the collision on the triangle level and not entity level. The difference can be in several magnitudes.
Quite an interesting question. So far my targeting systems do random raycasts (or random with some limits like only upper hemisphere) - actually it’s surprisingly enough at least for debug purposes (as real gunners can’t change aim instantly anyway), but It’s always good to know how to potentially optimize in the future.
A vector is a direction, not a position. The dot product is related to the angle between two directions. So it’s a way to find out which direction to turn to aim.
If that’s a problem, there is a possibility to simply interpolate between current facing quaternion and target one (obtained from, say, LookAt method), I presume. That will automatically include direction information so author will have to calculate just the absolute angle to make it possible at some constant rotation speed.
There is no reason to do any angle calculations… the dot product is already the cosine of the angle…which magically enough is exactly what you need to figure out how fast to turn.
Left vector is the direction vector that faces left.
lefttVector = myRotation.mult(Vector3f.UNIT_X); // assumes z forward.
99 times out of 100, that angleRAD is then fed back into a cos or sin somewhere in which case it was never necessary to have had the angleRAD in the first place.