- Home /
Problem with detecting if instantiated objects are overlapping
Alright, so the title basically sums up the question. I am working with instantiating a bunch of objects along a path which is literally just a stored list of Vector3 positions in the world, which works fine and it comes out looking something like this.
My issue is that the instantiated objects can be of variable size and shape (and even possibly variable rotation). So I am trying to run checks against the objects to see if they are overlapping and then remove the objects they are overlapping with so that is can look something more like this, so that is looks like a fluid path of objects one right after another close together but not touching (but without the minor overlapping of course. I simply manually placed those):
Here is my code for checking for doubles (Note: That each instantiated object is added the the list "_objs" before this function is called)
void RemoveDoubles(){
for (int j = 0; j < _objs.Count; j++) {
int k = 0;
foreach (GameObject obj in _objs) {
if (_objs [j] == obj) {
break;
}
bool overlapping;
Collider col1 = _objs [j].GetComponent<Collider> ();
Collider col2 = obj.GetComponent<Collider> ();
overlapping = col1.bounds.Intersects (col2.bounds);
if (overlapping) {
_KillList.Add (obj);
Debug.Log("Object " + j + " is overlapping with Object " + k);
}
k++;
}
foreach (GameObject obj in _KillList) {
_objs.Remove (obj);
Destroy (obj);
}
}
_objs.Clear ();
_KillList.Clear ();
}
The idea is that I check the first object in the list against every other instantiated object in said list. I then add the overlapping objects to another list to be removed from the list and destroyed in the world. However, it seems I am doing something wrong as this is not working as intended and it may just be the heat where I am at but my brain is broken and this one thoroughly has me stumped at the moment.
Also I was wondering If I am simply over complicating this and if anyone has any ideas of an easier, more straightforward way of checking / achieving this.
Answer by AlwaysSunny · Jun 27, 2015 at 03:31 AM
Why not address the problem during the placement stage? Doing it after the fact might be a useful skill in other scenarios, but it is entirely wasteful here. Just place the objects so they never overlap in the first place.
Decide the rotation and scale of the next object.
Look at the next position in the position list.
Use Physics.OverlapSphere to see if the space is occupied.
If so, record that position as the last examined, and goto step 2.
When you find a position that won't overlap, place the object.
Record the index of the position used; the following position will be the next examined by step 2.
WaitForFixedUpdate
Go to step 1.
Assuming you want more control, and that all these objects can be represented by boxes, you could use a box collider instead of CheckSphere.
Regardless of the approach, you will probably need to perform this algorithm over N frames in a coroutine with a WaitForFixedUpdate (step 7) because new colliders will not necessarily register their existence until the next frame. If your positions are cleverly spaced according to the average size of these objects, it shouldn't be too big of a problem.
If you don't like the idea that this algorithm executes over time, consider that the alternative is a rather substantial "hitch" or period of nonresponsiveness, which is a much more egregious faux pas in the minds of most users, not to mention spawning dozens or hundreds of unnecessary objects.
If you want "nice" placement on a spline, including control over the rotation along the spline, there are approaches for that that will produce much more aesthetically pleasing results. This involves using a true spline implementation, as opposed to a list of positions. It would also make this placement stage quite trivial, assuming you could make some decisions about average scale, and that the spline is precalculated. These are fairly well documented general spline topics.
If you really want to stick with your approach of placing first, solving for overlap second; the general shape of your approach makes sense, but I didn't proofread it to spot flaws or errors. Your written English description of the solution is sensible enough. Start with the first object and walk out until you find one that doesn't overlap, remove those in between, then continue from that first non-overlapping object. This work could / should also be spaced out over several frames.
Regardless of your selected approach, the most important optimization involves ensuring you are performing as few checks as possible, e.g. by ensuring your spline positions are cleverly spaced. Also, you could skip positions in your list (step 2) until the distance between the last placed object and the next placement test is roughly twice the average radius of your objects.