Prefabs jumping on instantiate. (random spawn)

Hello. So… I’ve opened about a dozen tabs searching to figure this out, but although this seems simple I had no luck …
So I’m trying to press a button and spawn capsules(units) in random places, around a cube(base). When instantiating a capsule too near to another one, the capsule jumps in the sky.
I’ve tried using a SphereCast to detect if any other unit is in the way. Doesn’t seem to work…This is mostly the code attached to my cube(base):

void OnGUI () 
{
     Vector3 SpawnPoint = new Vector3(transform.position.x + Random.Range(-5.0F, 5.0F), 0.1f, transform.position.z + Random.Range(-5.0F, 5.0F));

     if(GUILayout.Button("Unit"))
     {
          Vector3 rayOrigin = SpawnPoint;
          rayOrigin.y += 2;
          RaycastHit hit;
          if(Physics.SphereCast(rayOrigin, 1, Vector3.down, out hit))
          {
               print (hit.collider.tag);
               if(hit.collider.tag != "Unit")) Instantiate(Unit, SpawnPoint, Quaternion.identity);
          }
     }
}

Note: You can see I check for the tag “Unit”. I DID make sure the prefabs have that tag. It doesn’t instantiate when it finds the tag “Unit”, but most times it finds the tag to be “Terrain” even when a unit IS in the way.

Can you please help me and all others that want to implement random spawning? Ty :slight_smile:

I believe this will help http://docs.unity3d.com/Documentation/ScriptReference/Physics.SphereCastAll.html

SphereCastAll returns an array of RaycastHits instead of just a single one which as you found out sometimes is “Terrain” instead of “Unit”, then all you have to do is modify your code slightly to cycle through all the RaycastHits and make sure none of them are one of the "Unit"s. Hopefully that helps some.

Thank you for answering. I was thinking of trying SphereCastAll but I don’t know how to get the information from the hits in the array. I coded in simple Unity code for so long that I forgot some basics. I’m guessing it works as normal C# arrays in general. I’ll brush up on my C# and try it, thank you for the answer, will come back to post if it worked.

Ok so I added SphereCastAll but it still doesn’t seem to work. I even made the radius to 100 so it should be impossible not to detect a unit already built.
Here’s the modification to the SphereCast code:

			 	RaycastHit	[] hits = Physics.SphereCastAll(rayOrigin, 100, Vector3.down, 10);				
				for (int i=0; i<hits.Length; i++)
				{
					if (hits[i].collider.tag == "Unit") {print("Unit in way"); break;}
					else if (i == hits.Length - 1) {print ("empty"); Instantiate(Unit, SpawnPoint, Quaternion.identity);}
				}

So in short it checks every time if the tag is “Unit”, and at the last element of the array if there is no unit then it instantiates… why is it not working?!

I’m not really familiar with the SphereCastAll method but I’m thinking

Physics.OverlapSphere

does what you want.

It returns all colliders in the specified sphere.

I’ve seen some stuff about OverlapSphere but didn’t understand it before. You were right Thoeppner, it works excelent :smile: Thank you very much all! I probably wouldn’t knew how to use it before looking better into SphereCastAll.

So the final code, for all those interested in (random) spawning and not worrying about instantiating too close to other prefabs:

    public GameObject Unit;

    void OnGUI ()
    {
         Vector3 SpawnPoint = new Vector3(transform.position.x + Random.Range(-5.0F, 5.0F), 0.1f, transform.position.z + Random.Range(-5.0F, 5.0F));
     
         if(GUILayout.Button("Unit"))
         {
                Collider[] hits = Physics.OverlapSphere(SpawnPoint, 1);       
                for (int i=0; i<hits.Length; i++)
                {
                    if (hits[i].collider.tag == "Unit") {print("Unit in way"); break;}
                    else if (i == hits.Length - 1) {print ("empty"); Instantiate(Unit, SpawnPoint, Quaternion.identity);}
                }
         }
    }

P.S. If it’s still too close just adjust the radius of the OverlapSphere to higher than 1