Help detecting collisions on complex objects with teleportation

I’ve been working on this all day and I need some help. I’m trying to spawn a bunch of buildings randomly in an area, but they keep spawning on top of and inside each other. Here’s an album with my code and a screenshot of the spawning behavior:

Each building is a single color, made up of multiple box colliders with kinematic rigidbodies with IsTrigger unset. I randomly generate the building then send it to the TestCollision function. To test for collision, I create a new gameobject with a kinematic rigidbody, a trigger boxcollider, and this teleport tester script (code in the album). Then I disable the original game object, wait for a fixed update, and check the allClear variable.

The problem is, it doesn’t detect collisions most of the time. When I spawn 100 buildings, it will detect maybe two collisions (triggering a retry), but it won’t detect the dozen or so other collisions and buildings end up on top of one another.

Does anyone know what might be causing this? I’m guessing it’s got something to do with that I’m putting the placeholder game object into other colliders which aren’t moving, but I tried doing a WakeUp on the placeholder’s rigidbody and that didn’t work.

I don’t know a good guide, but I’ll try to explain simply. I think formatting is better in the answer section so I put it in here.

Coroutine’s are perfect for doing heavy work broken up into several frames.

Examples:

I use them for cross-fading music, moving objects, and even to create a tiled game board with thousands of pieces in front of the player, but I only spawn a few pieces per frame. So instead of a loading-time/game hiccup by trying to do a heavy job at once, it keeps the framerate smooth by breaking it down into simple executions spread out over many frames…

To use it:

Basically inside a coroutine you create a loop, and at the end of that loop tell it to wait for the next frame (or you can have it wait based on time). .

So code for spawning your buildings may look like this (C#):

public class Buildings {
 
  public int m_iMaxBuildings;

 public Init() {
  m_iMaxBuildings = 250;
  StartCoroutine(SpawnBuildings());  //<-- this is how you start it
 }    
 public IEnumerator SpawnBuildings() {
    Debug.Log("I will only print once"); //<--before the loop
    for (int i=0; i < m_iMaxBuildings; ++i) { // <-- start the loop, any kind of loop.
        SpawnASingleBuilding();
        yield return null;   // <-- here it pauses this function
        Debug.Log("This is the next frame"); // <-- it will start here next frame
    }                //<--end of for-loop, you can put more or do nothing else-->
     yield break;  //<--this is NOT necessary, i put it here to show you how to if 
                   //   you need to abort early, it will terminate the the function
 }

 public void SpawnASingleBuilding() {
      // ... your code here ..
 }
};  //end class

On a side note, I also use it to delay actions once in awhile like playing particle effects for example. You can have as many yield… statements as you want as well.

I used a similar trick to detect objects inside a given volume, but had to force collision calculation with a simple trick: assign transform.position to rigidbody.position. Take a look at my answer to this question.

EDITED: Complementing @SinisterRainbow’s answer: since the collision detection function is a coroutine, you should chain the main loop to it. Chaining coroutines is much like a regular function call: control is transferred to the called routine and only returns to the caller when the routine ends. But there’s a problem: a coroutine can’t return any useful value (coroutines always return IEnumerator). In C# you could use the out or ref keywords to get the return value in a variable passed by reference, but in JS the only way is to use a class variable (class variables are always passed by ref). The JS code could be something like this:

class AllClear { // declare the AllClear class
  result: boolean; // this variable will receive the returning value
}

private var allClear = AllClear(); // create a variable of type AllClear

// SpawnBuildings is a coroutine
function SpawnBuildings(howMany: int): IEnumerator {
  while (howMany > 0){
    var toSpawn = SelectRandomBuilding(); // randomly select a building 
    do {
      var pos: Vector3 = CalculateRandomPosition(); // draw a random position
      yield TestCollision(toSpawn, pos, allClear); // chain to the test collision coroutine
    } while (allClear.result == false); // repeat until clear position is found
    SpawnBuilding(toSpawn); // spawn the building
    howMany--; // decrement counter
  }
}

// TestCollision is a coroutine
function TestCollision(model: GameObject, position: Vector3, isClear: AllClear): IEnumerator{
  isClear.result = false; // initialize result
  // do the collision test, then assign the result to isClear.result
  if (model doesn\'t collide with anything) isClear.result = true;
}

NOTE: A couroutine always returns IEnumerator, but you don’t need to explicitly declare its return type in JS (opposite to C#): the compiler automatically infers this when you use a yield statement inside a function. Despite this, I declared the IEnumerator type just to state that the functions above are coroutines.