Selecting Closest Item To Pick Up

Hi all,

I’m trying to create functionality that will find a “selected object” within a game so that I can add effects to that object. There’s no cursor so it’s really just any object that can be “picked-up” that is within range of the player. When multiple objects are within reach of the player, I want the closest one of the bunch to be “selected”.

I’ve created a trigger collider for the player that will identify whenever an object with the tag “Pickup” enters the trigger. My plan is to add the game objects that enter the collider to an empty list, and remove them from the list anytime they leave the collider. The list would then calculate the distance of each object to the player and return the closest one each frame.

Is this the best way of achieving something like this? If so, how do I do it?

Here is what I have so far in the Player object’s script. I have float “dist” picking up the distance for each object from the player, but now I’m not entirely sure how to proceed. In fact, I’m confused how one float variable could have more than one distance assigned to it:

List<GameObject> pickupsInRange = new List<GameObject>();
void OnTriggerEnter(Collider collision)
    {
        switch (collision.gameObject.tag)
        {
            case "Pickup":
                pickupsInRange.Add(collision.gameObject);
                break;
        }
    }
    void OnTriggerStay(Collider collision)
    {
        switch (collision.gameObject.tag)
        {
            case "Pickup":
                foreach (GameObject pickup in pickupsInRange)
                {
                    float dist = Vector3.Distance(pickup.transform.position, transform.position);
                }
                break;
        }
    }
    void OnTriggerExit(Collider collision)
    {
        switch (collision.gameObject.tag)
        {
            case "Pickup":
                pickupsInRange.Remove(collision.gameObject);
                break;
        }
    }

It sounds like what I’d do, except I don’t see why you’d need to recalculate every frame. If it needs fast updating you’ll probably still get good results updating every 0.1 seconds, so at 60 frames per second that would be 5/6 reduction in the number of Vector3.Distance calls. You can adjust the interval with play testing.

Also, don’t do the looping through the list in OnTriggerStay. You’re looping through the entire list for each Pickup object in range. So 5 Pickup objects results in looping the list 5 times over, each frame. Do it in Update or a Coroutine IMO.

Okay, I’ll move it to update, but I’m not sure what I would do next. At that point I would just have assigned a variable with the distance to player for each object in range, although wouldn’t the float “dist” just end up getting overwritten by the last object’s distance?