- Home /
Checking to see if BoxCollider intersects with another collider doesn't work.
Hi, my problem is that the bounds.Intersects doesn't work when I check it (or is just not triggering a move).
What I'm trying to do is, I have generated many "cells" and those cells have BoxColliders attached to them, but when they get instantiated the size of the collider is determined.
Here is my Cell script (generating a quad just for visual representation so I can see whether or not it overlaps):
using UnityEngine;
using System.Collections;
public class CellSize : MonoBehaviour {
public int x, z;
void Start() {
BoxCollider collider = this.gameObject.GetComponent<BoxCollider>();
collider.size = new Vector3(x, 1, z);
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.parent = this.transform;
quad.transform.position = this.transform.position;
quad.transform.eulerAngles = new Vector3(90, 0, 0);
quad.transform.localScale = new Vector3(x, z, 0);
}
And this is the part of code that I have in my GenerationManager script that should move the cells away from each other if they are intersecting:
private void Separate(Transform childObj) {
BoxCollider childObjCollider = childObj.GetComponent<BoxCollider>();
foreach (Transform child in this.transform) {
BoxCollider childCollider = child.GetComponent<BoxCollider>();
if (childObj.transform.name != child.transform.name) {
while (childObjCollider.bounds.Intersects(childCollider.bounds)) {
childObj.position += new Vector3(5, 0, 5);
//childObj.position = child.transform.position + ((childObj.transform.position - child.transform.position).normalized * 5f);
}
}
}
}
But apparently it still doesn't move the objects away from each other, but I put a debug.log inside the while loop, so I'm assuming the colliders know they are intersecting, but the objects just aren't moving.
Here's a picture showing the end result of this:
As you can see the colliders are still overlapped.
There's a lot of code, and a nested loop. I'd guess some other part is messing up somewhere.
If you really think it's bounds.Interesects, I'd make a small test somewhere else. $$anonymous$$aybe just that inner while loop against a pre-placed cube. See if it can run 3-4 times to un-overlpa itself. I've read how moving an object can require a physics step to "register" it with the collision system, but I've never seen that happen. But still, worth a test if it's bothering you.
Well I tried it by changing the while loop to just an if statement and put a debug.log, and apparently the two colliders are intersecting, but it's just not getting called.
This is what it looks like:
You're checking for if you're looking at the same object with:
if (childObj.transform.name != child.transform.name)
Before 5.1 all newly instantiated objects had the same name, so that would cause that check to never return. Anyways, you get exactly the same result, but faster, with:
if (childObj != child)
Try that.
Baste: it doesn't work. The debug.log message still isn't showing up even though both boxcolliders are DEFINITELY intersecting.
$$anonymous$$y guess is either the Generation$$anonymous$$anager script is not attached to the GameObject that holds all the cells as children, or Seperate() is not called with the right parameter.
Just another thought, maybe another script is setting the initial positions of the cells constantly
Answer by llndprkr · Nov 09, 2015 at 02:40 PM
@TrivialRoo It looks like you can achieve your result (and streamline your code) by checking "Is Trigger" in the Inspector Tab for your colliders and then using one or more of Unity's built-in Trigger methods in your script:
OnTriggerEnter();
OnTriggerStay(); //This is the one you're apparently looking for
OnTriggerExit();
The Unity Team published a nice video on Trigger collision methods: http://unity3d.com/learn/tutorials/modules/beginner/physics/colliders-as-triggers?playlist=17120
Once you detect the collision, you can add a repelling vector to the colliding object (called "other" in the code below). The second "AddForce" line applies the opposite force vector to the object running the script. (NOTE: this code passed muster in my compiler, but it's after 5am and I need to go to bed so didn't test it.)
void OnTriggerStay(Collision other)
{
Vector3 repellingVector = new Vector3();
repellingVector = other.transform.position - gameObject.GetComponent<Transform>().position;
other.rigidbody.AddForce(repellingVector, ForceMode.Force);
gameObject.GetComponent<Rigidbody>().AddForce(-repellingVector, ForceMode.Force);
}
"ForeceMode.Force" is the default way to apply physics forces and is included here only for illustration. Three other force modes are available in Unity 5.2 to modify the behavior of the physics engine in certain ways.