Check if created object overlaps before spawning?

So I have a player that can spawn a random prefab off a list in front of them. The only problem I’m having is that these objects can overlap, which I don’t want. I tried using a raycast, but this only checks if there is nothing on the exact mouse position, not the entire object/prefab.
Here’s my spawn code:

    if (Input.GetButtonDown("Fire1"))
    {
      Vector3 fwd = transform.TransformDirection(Vector3.forward);

      if (!Physics.Raycast(transform.position, fwd, 3)) // checks if there isn't any object 3 meters ahead of camera position
      {
        var mousePos = Input.mousePosition; // gets the mouse position
        mousePos.z = 3.0f;       // The object will be placed 3m away from the camera position
        var objectPos = Camera.main.ScreenToWorldPoint(mousePos); // puts the objectPos to the mousePos
        Instantiate(prefabList[Random.Range(0, (prefabList.Count))], objectPos, Quaternion.identity); // Spawns a new random object from the list at the mouseposition
      }

I have tried using a collider script in every spawned prefab, but this would start to delete eachother, because it keeps checking even after being spawned, code below:

  void OnTriggerEnter(Collider col)
  {
    if (col.gameObject.tag == ("Spawns"))
    {
      Debug.Log("On trigger enter activated!");
      Destroy(this.gameObject);
    }
  }

So my question is if anyone knows how to make it so the prefabs I spawn from my list won’t overlap/the click won’t do anything if it overlaps with another object?

You could add a bool (isSpawning) defaulted to true. Then in the OnTriggerEnter only check to delete the object if isSpawning is true.

Next, make the Start be an enumerator IEnumerator Start(). Then in Start, add a yield null; to allow a frame to pass (this should allow the physics step to run, I believe, if not add a second yield null), then set isSpawning to false. That line will only run if the script is still active and it will prevent further checks to delete itself.

1 Like

Thanks so much, this seems to have almost completely fixed the problem!
I only have this weird problem where if I click multiple times after a few clicks on the same spot it will still be able to spawn an object that overlaps

Hmm. I suppose that could happen if you picked an empty spot and were able to click it twice in the same frame but I’m not sure that is even possible.

Are you using just a single yield null in IEnumerator Start()?

1 Like

Yes I changed it to this:

  bool isSpawning = true;

  IEnumerator Start()
  {
    yield return null;
    isSpawning = false;
  }
  void OnTriggerEnter(Collider col)
  {
    if ((col.gameObject.tag == ("Spawns")) && isSpawning)
    {
      Debug.Log("On trigger enter activated!");
      Destroy(this.gameObject);
    }
  }
}

The deleting is now completely fixed, it still only sometimes still overlaps the objects

EDIT: Adding the second yield return null as you said before the isSpawning = false; seems to have fixed it somehow

Any idea why this is though? In case I run into it again some day

Sorry, just to be clear, which bit are you questioning? Are you asking why the yield return null; is necessary in the Start() method to make this code work?

1 Like

I’m wondering why the code doesn’t 100% work with 1 yield return null, but it does work with 2.
Does it somehow skip the first frame sometimes?

Have to be honest, I’m with you on that one - I’m not sure why either. :eyes: It would have to be debugged to find out why.

1 Like

Alright, guess I’ll just stick with this fix then, maybe I’ll somehow find out later.
Thanks for all the help!

1 Like

You’re welcome. Best of luck with the rest of your project. :slight_smile:

Use the physics.overlap sphere, box, capsule methods to make sure the space you want is clear before spawning the object.