Find gameObjects at certain distance

I need to find game objects with a distance of ‘x’ from the current game object.

GameObject.Find functions does not give this feasibility to me.

If there any other way to achieve this ?

Ex: I have my hero who is surrounded by ‘n’ number of enemies.
I need to find out number of enemies at 1 unit distance. Any body can help me with this problem ?

Just add a collider to your player with radius X. If anything walks into the collider, add them to a list.

Might be better to just do a Physics.OverlapSphere and get an array of nearby colliders straight away.

http://docs.unity3d.com/Documentation/ScriptReference/Physics.OverlapSphere.html

2 Likes

Try this:

var  Distance : Vector3;
var DistanceFrom : float;
var hero : Transform;
var enemy : transform; 

function Update(){
Distance = (enemy.position - hero.position);
Distance.y = 0;
DistanceFrom = Distance.magnitude;
Distance/=DistanceFrom;
}

It should calculate the distance between the hero and the enemy.

Why put them in the array?

This doesn’t fit the requirements. OP wanted all objects within a given radius. This calculates the distance between 2 given objects every frame.

How else do you propose working with a collection of something?

Can you give an example Kelso, if you don’t mind.

Oh, i thought that was what you wanted. My bad.

An example of what?

Using it to work with a collection of something?

I still don’t understand what you’re talking about. An array is a collection of objects. It’s also what Physics.OverlapSphere gives you back.

Are you asking specifically about how to use Physics.OverlapSphere?

Come on Kelso… yeah how would you do what this guy is asking?

Er - ok, you hadn’t really been clear up to this point.

Assuming that the GameObjects in question have colliders attached to them-

// returns an array of objects within radius of origin or null
// if nothing is nearby
public GameObject[] GetNearby(Vector3 origin, float radius)
{
    Collider[] cols = Physics.OverlapSphere(origin, radius);
    if (cols.Length > 0)
    {
        GameObject[] nearby = new GameObject[cols.Length];
        for (var i = 0; i < cols.Length; i++)
        {
            nearby[i] = cols[i].gameObject;
        }
        return nearby;
    }
    return null;
}

Of course, if you didn’t want the abstraction just use the Physics method directly

// find everything around me within 10 meters
Colider[] nearby = Physics.OverlapSphere(transform.position, 10);
for (var i = 0; i < nearby.Length; i++)
{
    // do something awesome
}

I appreciate your help Kelso, but I meant a example of why you would do this. Like what situation would you use this in? Sorry I wasn’t more clear.

Whenever you need to find objects that are within a certain distance of something. Idle units in our game - Fractured State - use it as a sort of “radar ping” to see if any enemies are nearby. We use that instead of a collider trigger so that it doesn’t get evaluated constantly and can stay in step with our line of sight evaluations (via a Coroutine).

I’ve also seen it used as a local avoidance method in steering behaviors.

Does that answer your question?

Yes, thank you.

Thanks Kelso, it works for my situation. Thanks for your time all you guys !

i know this was 10 years ago lol, but in case anyone gets to this post, if you want to filter a certain kind of gameobjects its better to use a list for the objects nearby and then use.ToArray().

    [/ICODE]
    [SerializeField] private float _distance;
    [SerializeField] private GameObject[] enemiesInRange;

    void Update()
    {
        enemiesInRange = GetNearby(transform.position, _screamDistance).ToArray();
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(transform.position, _distance);
    }

    public List<GameObject> GetNearby(Vector3 origin, float radius)
    {
        Collider[] cols = Physics.OverlapSphere(transform.position, _distance);
        if(cols.Length > 0)
        {
            List<GameObject> nearby = new();
            for (int i = 0; i < cols.Length; i++)
            {
                if(cols[i].GetComponent<EnemieClass>() != null)
                {
                    nearby.Add(cols[i].gameObject);
                }
            }
            return nearby;
        }
        return null;
    }

this way you’ll get only the gameobjects with the EnemieClass Component in your enemiesInRange array, instead of getting a lot of empty gameobjects if you used an array as nearby.

There’s no good reason to necro a thread, especially one that’s 10 years old. Please don’t do this.

Also, what you’ve posted here isn’t really good advice TBH.

You’re generating both an array and a list just to get some objects. That’s extremely wasteful and will produce a lot of GC waste. This is why OverlapSphereNonAlloc exists. In the very least, you should be passing in the list so it’s reused rather than producing a new one each call. You could also just step through the array and if something isn’t relevant then simply move the final entry to this entry and reduce the count to look at in the array returning the array and how many entries are valid. Finally, it’d be better to organise your project so that enemy are on a layer and you’d only expect that component on such things therefore specifying the enemy layer in the query will always give you the correct results; not always possible in more complex games but certainly the best option if available.

There’s lots of better ways beyond creating more GC waste.

3 Likes