How do I check whether there is already an object in the position I'm in?

Hey Folks :slight_smile:

I’m working on a problem right now and I’m a bit stuck. I randomly distribute a number of objects on a grid. Each position is allocated like this:

Instantiate (Object,Vector3(Random.Range(minRange,maxRange),1,Random.Range(minRange,maxRange)), transform.rotation);

Now the problem I’m facing is that some of the objects are spawned at the same position. I would like to the object to re-position itself in that case. How can I detect whether there is an object in the same spot as the newly spawned object?

I tried solving it with function OnTriggerStay (other : Collider) but since the object is directly spawned in the same spot it doesn’t seem to work.

Do you have any hint where the problem lies and maybe can give me a hint on how to solve the problem?

Cheers!

Dawnreaver

Look into using Physics.OverlapSphere:

1 Like

or just calculate a Vector3.Distance();

Best practice is u make every instantiated object as a child of one empty parent object. Now before going to instantiate a new object get all child objects of that empty parent object and compare their transform.position is match with ur new random.range value. Thats why u can check if a object already there or not.

Is the method to compare Children documented in the Scripting reference?

Apply this code on a empty object named parentObject and check this out its work or not.

using UnityEngine;
using System.Collections;

public class instantiateObject : MonoBehaviour
{
	[HideInInspector]
	public Transform[] objectList;
	
	
	public GameObject prefab;
	private Vector3 position;
	
	void Awake(){
		InvokeRepeating("createObject",0.1f,2.0f);
	}
	void createObject ()
	{
		position= new Vector3(Random.Range(1,3),1,1);
		objectList = gameObject.GetComponentsInChildren<Transform> ();
		foreach (Transform obj in objectList) {
			if (obj.transform.localPosition==position){
				return;
			}else{
				var temp=(GameObject) Instantiate(prefab,new Vector3(Random.Range(1,3),1,1),Quaternion.identity);
				print (temp.gameObject.transform);
				temp.transform.parent=gameObject.transform;
			}
		}
		
		
		
	}

Cheers! I’ll have a go at it. Looks like I should start learning how to script in C# though :smile:

The other suggestions might work in some circumstances, but none of them take into account the size of the objects. Therefore you might still get objects that overlap with each other (unless they’re smaller than one unit for this scenario).

With the code that Ram posted, it might not work because comparing Vector3 isn’t very reliable. Vector3 is a class comprised of float values, and a quick search on Google will tell you that directly comparing floats is an accident waiting to happen. It would be better to work out the difference between the two positions and check if it’s under a certain small threshold. His code also doesn’t factor in that the local position of an object might be different from it’s world position.

Actually the Vector3’s I use are integers. The game is grid based so I figured nice whole numbers make my work alot easier :smile:

Ok So this is what I came up with:

#pragma strict
var objectCount : int = 20;
var myObject : GameObject;
var minRange : int = -5;
var maxRange : int = 5;
var randomPos :Vector3;
var objectPosition = new Array();
function Start () 
{
// create an Object for each level
for (var a = 0; a < globalVars.levelCount; a++)
	{
		// create a randomposition
		randomPos = Vector3(Random.Range(minRange,maxRange),1,Random.Range(minRange,maxRange));
		//start searchig for values in the array
		for ( var value in objectPosition)
			{
				// if the value is not inside the array
				if ( value != randomPos)
					{
						// spawn an object
						Instantiate(myObject,randomPos, transform.rotation);
						objectCount -= 1;
						objectPosition.Add(randomPos);
					}
			}
	}
}

function Update () 
{

}

BUT it doesn’t work. When compiling the script Unity isnot prompting any errors. Any suggetsion where I went wrong?

Cheers!

Dawnreaver

Your loop logic is screwed up. When a = 0, objectPosition is empty, so the foreach loop doesn’t run at all. You need logic more like:

do
{
  randomPos = Vector3(Random.Range(minRange,maxRange),1,Random.Range(minRange,maxRange));
} while(objectPositions.Any(p => p == randomPos));

Instantiate(myObject, randomPos, transform.rotation);
objectPositions.Add(randomPos);

What does “p” do?

Here this is simple by using Vector3.Distance();

var dist = Vector3.Distance(GameObject.Find("object").transform.position, transform.position);
//Then check how far they are away.
if(dist < .2)//Checks if there within .2 of each other.
	 {
	//do something
	 }

Why use ‘Any(p=> p == randomPos)’ when one can use ‘Contains(randomPos)’ :stuck_out_tongue:

@OP using the ‘p’ in Any will fail because US doesn’t allow that lambda syntax IIRC - you’d need a more verbose form. For either method to work you’ll need to import System.Linq IIRC. You may have to change objectPosition to a List for this to work - in which case you’ll need to import System.Collections.Generic IIRC.

Did I miss anything?

Uhm …this is C# right ? It’s just I never touched it :smile: Is there a similar way to use “Contains(randomPos)” in java script?

I couldn’t remember whether that skanky Array class has a Contains method or not so I went with the safer option… If its got one then sure, go for it. You’d be better off using HashSet though.

Is there a “HashSet” in JS? I had a browse in the scripting reference and couldn’t find anything about it.

It’s in System.Collections.Generic. I believe that everything in the standard namespaces is available in JS, yes.

So I had some help from a friend. Here is the solution to the problem:

var myObject : GameObject;
var minRange : int = -3; // min spawn range
var maxRange : int = 3; // maxspawn range
var randomPos :Vector3; // random position genearted
var checkposition:Vector3;  // used to check wether the position is already in the array
var place:boolean = true; // can the object be placed?
var objectPosition = new Array(); // array that contains used  up positions

function Start ()
    {
       
        // create an Object for each level
        for (var a = 0; a < globalVars.levelCount; a++)
            {
                // create a randomposition
                randomPos = Vector3(Random.Range(minRange,maxRange),1,Random.Range(minRange,maxRange));
                //start searchig for values in the array
                place = true;
               
                for ( checkposition in objectPosition)
                    {
                        //if the value is not inside the array
                        if ( checkposition == randomPos)
                            {
                                place = false;
                            }
                    }
       
                if (place == true)
                    {
                        //spawn an object
                        Instantiate(myObject,randomPos, transform.rotation);
                        objectPosition.Add(randomPos);
                    }
            }
    }