Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to find the nearest object

Discussion in 'Scripting' started by Corva-Nocta, Oct 13, 2015.

  1. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    I have a click to move script up and running perfectly but I will eventually want to add in things that the player will use, doors, treasure chests, monsters, etc. The game functions on a grid and when a space is clicked on the player moves to that grid space, but I will need to make it so that is a useable object is clicked the player will move to the nearest grid space then use the object. I am having trouble trying to locate the nearest grid space, how does one search for the nearest object from another object? Is there an effective way to find that object within a distance? What should I be looking for?

    C# is preffered
     
  2. vintar

    vintar

    Joined:
    Sep 18, 2014
    Posts:
    90
    Code (csharp):
    1. public GameObject GetClosestObject()
    2. {
    3.   float closest = 1000; //add your max range here
    4.   GameObject closestObject = null;
    5.   for (int i = 0; i < MyListOfObjects.Count; i++)  //list of gameObjects to search through
    6.   {
    7.     float dist = Vector3.Distance(MyListOfObjects[ i ].transform.position, player.transform.position);
    8.     if (dist < closest)
    9.     {
    10.       closest = dist;
    11.       closestObject = MyListOfObjects[ i ];
    12.     }
    13.   }
    14. return closestObject;
    15. }
     
    Eater_Games likes this.
  3. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    sweet thanks!

    actually I'm having a hard time getting this script to work :(
    Just trying to set up how to find the nearest grid space (right now just a cube object) to another object (another cube object) is there a simple way to do that? I've seen a lot of scripts that find objects with a specific tag, but I need a simple find nearest object within 1.5 with tag "walkable"
     
    Last edited: Oct 13, 2015
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    if you are only looking at a small area around a specific point you could try an overlapsphere check to pick up the objects within range.

    http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html
    (think raycast "smartbomb" :D)

    this will return a list of the colliders within the radius, you can then iterate over that list per @vintar 's code


    if you want to get "snazzy" you can sort lists using the lambda functions supported in the linq namespace... but I think it might be best to work a solution "by hand" before figuring out that (google "unity linq sort distance" should get you examples of this)
     
  5. vintar

    vintar

    Joined:
    Sep 18, 2014
    Posts:
    90
    Yes sorry, I was going to mention doing an overlap sphere if you had no list of object, and totally forgot to add it, my bad :)
     
  6. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Excellent answers in here. Couple of extra thoughts:

    Code (CSharp):
    1.  
    2. //I would use a couple different methods with different overloads for different purposes.
    3. //Sometimes you'll want to do a physics cast to find the gameObjects, but sometimes they wont
    4. //have colliders. Also, you might keep a reference to a collection of them.
    5. //The first two overloads use the last.
    6.  
    7. //I made these static because they don't require a reference to 'this'. This way you could
    8. //add them to a static Utility class, or make them accessible from your Custom class.
    9.  
    10. //Quick and easy. Searches all gameObjects and returns the closest to the origin.
    11. static GameObject ClosestObject(Vector3 origin)
    12. {
    13.     var gameObjects = FindObjectsOfType<GameObject>();
    14.     return ClosestObject(origin, gameObjects);
    15. }
    16.  
    17. //Returns all gameObjects with colliders within the given range of the given origin.
    18. static GameObject ClosestObject(Vector3 origin, float range)
    19. {
    20.     var list = new List<GameObject>();
    21.     Collider[] found = Physics.OverlapSphere(origin, range);
    22.  
    23.     foreach(var collider in found)
    24.         list.Add(collider.gameObject);
    25.    
    26.     return ClosestObject(origin, list);
    27. }
    28.  
    29. //Returns the closest gameObject in a given collection of gameObjects.
    30.                        //IEnumerable so that you can pass any collection into this method. Array, List, Dictionary.Values, ect
    31. static GameObject ClosestObject(Vector3 origin, IEnumerable<GameObject> gameObjects)
    32. {
    33.     GameObject closest = null;
    34.     float closestSqrDist = 0f;
    35.  
    36.     foreach(var gameObject in gameObjects) {
    37.         float sqrDist = (gameObject.transform.position - origin).sqrMagnitude; //sqrMagnitude because it's faster to calculate than magnitude
    38.  
    39.         if (!closest || sqrDist < closestSqrDist) {
    40.             closest = gameObject;
    41.             closestSqrDist = sqrDist;
    42.         }
    43.     }
    44.  
    45.     return closest;
    46. }
     
  7. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Thanks all! I think that overlap sphere is just what I'm looking for. I could see having a list of all the game objects working, but as the game grows in size wouldn't that eat up more processor power? I was thinking just a simple raycast from the object to find what grid spaces are closest. Guess its not as easy as I was hoping. Just need something local to find the transform of the nearest grid location so I can move the player there.
     
    Last edited: Oct 14, 2015
  8. Persona001_ID_Miijii

    Persona001_ID_Miijii

    Joined:
    Apr 16, 2019
    Posts:
    2
    I want to thank you a million!!! After some time and effort, I finally got my lock on system to work. After countless searching and tweeking! X3 I know this is an old forum post, but if you're out there, thank you!!! x3
     
    infinitegamesDS likes this.