Select and deselect objects based on distance.

Hi,

I have some objects in the scene and am using the following script to determine the distance of the objects to my camera target and playing an animation on the closest object when its distance is below a certain distance.

    private GameObject[] geoTags;
    public Transform closestGeoTag;

    private void Start()
    {
        closestGeoTag = null;
    }

    private void Update()
    {
        closestGeoTag = GetClosestGeoTag();
        //playing anim here
    }

    public Transform GetClosestGeoTag()
    {
        geoTags = GameObject.FindGameObjectsWithTag("geotag");
        float closestDistance = Mathf.Infinity;
        Transform trans = null;

        foreach (GameObject geo in geoTags)
        {
            float currentDistance;
            currentDistance = Vector3.Distance(transform.position, geo.transform.position);

            if (currentDistance < closestDistance && currentDistance < 0.15f)
            {
                closestDistance = currentDistance;
                trans = geo.transform;
            }
        }

        return trans;
    }

However I also want to play a different animation when the object moves further away again, basically “deselecting” the object.

Also some of the objects are quite close to each other. If both objects are below the threshold only the closer object should be “selected” but I feel like that could be solved by getting the first problem solved.

I based the script on this tutorial which actually seems to solve all of my problems but it is only done in 2D and I didn’t get it to work with 3D components.

Any help would be much appreciated!
Thanks in advance!

If I understand you correctly, then you want to check what object is closest, but only if it is within 0.15f distance. If it is closest, and within that distance, selection animation will be played. If another object becomes closest, you want to play selection animation on it, and deselection animation on the previously selected one. If selected object leaves 0.15f distance, and there’s no other object within, you just want to play deselection animation.


If the above is correct, then I suggest using another variable public Transform previousClosestGeoTag;, to store information about an object that was closest before the current one.

Then, inside Update, use code like this (actual animation calls omitted):

closestGeoTag = GetClosestGeoTag();
if (closestGeoTag == null)
{
    if (previousClosestGeoTag == null)
    {
        // currently nothing in range and nothing was before - do nothing
    }
    else
    {
        // there was a closest object before, but it left the 0.15f radius sphere
        // play deselection animation on previousClosestGeoTag
    }
}
else
{
    if(previousClosestGeoTag == null)
    {
        // new object entered 0.15f radius sphere
        // play selection animation on it
    }
    else if(closestGeoTag != previousClosestGeoTag)
    {
        // closest object changed
        // play selection animation on new one and deselection on previous one
    }
    else
    {
        // current closest object is the same as previous one, so no need to do anything
    }
}
// update previous object
previousClosestGeoTag = closestGeoTag;

Above code could be simplified a bit, but I just wanted to explicitly show all possibilities.

@MSachs
A suggestion for your script. Try this solution.

public Transform GetClosestGeoTag()
     {
         geoTags = GameObject.FindGameObjectsWithTag("geotag");
         // float closestDistance = Mathf.Infinity;
         // Transform trans = null; // put this in the field, not here.

         foreach (GameObject geo in geoTags)
         {
             if (trans == null) trans = geo;
             // float currentDistance;
             var lastDistance = Vector3.Distance(transform.position, trans.transform.position);
             var currentDistance = Vector3.Distance(transform.position, geo.transform.position);
 
             if (currentDistance < lastDistance && currentDistance < 0.15f)
             {
                 // closestDistance = currentDistance;
                 trans = geo.transform;
             }
             else
             {
                 trans = null
              }
         }
     return trans;
     }