# Creative solution needed: Need to adjust reach of grab mechanic

So I’ve got a ray that shoots out from my camera in an FPS to highlight and grab items.

I’m have an issue with the reach that needs a creative solution.

Obviously being a straight shot from the camera, items that are at the same height as the camera can be grabbed at further distances on the xz plain.

I’d like it so that the ray changes length based on where I’m looking, but REALLY don’t want to run Pythagorean’s theory every damn frame.

One thought I had was to add a capsule, shoot a ray from an empty gameobject towards the camera, take where it hits, then use the distance from that hit to the camera to get the range, and finally use a second ray to actually cast to items.

Seems like overkill though.

Any thoughts?

Have you actually tested this theory of yours? Sounds like you know the computers inside and out.
Besides you don’t need a raycast, just a distance to the object. But good luck doing it without the “expensive” Pythagoras theorem. I’ve met a guy once who did this with ifs, and to this day I can’t possibly fathom how. But what do you know, it seems there is this advanced alien knowledge out there, and some people have access to it, to do wonders in their frames in zero time.

Take the delta from the raycast to the touch point:

``````Vector3 delta = hitInfo.point - ray.origin;
``````

Now flatten the Y:

``````delta.y = 0;
``````

Now presto you can check `delta.magnitude` and get the effect you list as “What I want”

PS: computers can do a LOT of Pythagorean theories every frame: every call to .magnitude does one. Don’t let it fret you, unless you have like 10,000 raycasts each frame. With one or ten, you’ll be fine.

Did you consider using a SphereCast ?

How would sphere cast help?

I’m casting a ray to select items to pick up.

my problem is that things on the ground require the player to get much closer to the item.

If I used a sphere cast it would hit multiple items, and I don’t see how that would address the issue at all.

If you have many items and this is why you want to avoid Pythagoras, you’re supposed to limit the number of objects that are within a certain radius, by doing something that is cheap. This process is known as culling and should be enough to guarantee that you’ll never compute more than 2-4 distances per frame.

The cheapest way to cull is to implement an axis-aligned bounding box check, and then confirm the nearest object by computing squared distances, which is a lightning fast computation (sqrDistance = x * x + y * y).

If you do need to compute the actual distance in the end, you finally compute the square root of the winning result. (distance = Mathf.sqrt(sqrDistance))

In pseudocode

``````List<GameObject> candidates = testAABB(items, player.bounds);
float[] distances = findNearestOf(candidates, out int index);
Debug.Log(\$"nearest object is {candidates[index].name} at a distance of {distances[index]}");
``````

If you want an efficient distance comparator, you can grab my Min/Max extensions specifically tailored for this job. And if you don’t need the actual distance in the end, but just an index of the nearest point, you can use the method overload without it.

Here’s one possible implementation

``````int FindNearestColliderInside(Bounds bounds, List<Collider> items, out float distance) {
var bestSqrDist = float.PositiveInfinity;
int bestIndex = -1;

for(int i = 0; i < items.Count; i++) {
if(bounds.Intersects(items[i].bounds)) {
var diff = items[i].bounds.center - bounds.center;
var sqrDist = Vector3.Dot(diff, diff);
if(sqrDist < bestSqrDist) {
bestSqrDist = sqrDist;
bestIndex = i;
}
}
}

distance = (bestIndex >= 0)? Mathf.Sqrt(bestSqrDist) : 0f;
return bestIndex;
}
``````