- Home /
Problem with checking for intersection between two rotated objects
Scenario: The user places a tank. The user ROTATES the tank and when he is ok the rotation and the positions are sent to the server. In the server i have to make the tank, make all the boxes and colliders and check if it collides with another tank.
Problem: All the problems come from rotation because the bounds dont rotate they just expand.
I surround the tank with box collider, PrimitiveType.Cube that is with the size of the tank i add collider to the PrimitiveType.Cube too. I tried to make it work with all there objects.
I have done a lot of research and a lot of testing. I dont have problems with the objects or their rotation. And i dont want to use OnCollisionEnter and the others.
I am using bounds.Intersects but i can't make it work because the renderer.bounds does not rotate the bounds (rotation just expands them)
i have tried to get the mesh then .RecalculateBounds() i have tried sooo many things with (BoxCollider, Primitive.Cube, with the tank's mesh and renderer)
when i check for intersections of mesh.bounds it always tells me that they intersect even if they are far away
I just want to make a check that tells if they intersect like so: - if(AreThoseTwo_Rotated_Things_Touching(rotated_thing_1, rotated_thing_2)) where rotated_thing can be collider or primitive.cube or whatever but i need to make such a check without using OnCollisionEnter events triggers and so on
I need to surround the tanks with something rotate it and then check if this something intersects another something.
I will be incredibly grateful if someone tells me with what to surround the rotated tanks and then check if those things touch.
"i dont want to use OnCollisionEnter and the others"
Why are you averse to the collision detection system in Unity?
How are you checking the bounds intersection? Are you offsetting the values using each object's world position?
i am not sure what do you mean by offsetting with world position What i do with meshes (local coordinates) is:
$$anonymous$$esh first$$anonymous$$esh = firstObject.GetComponent<$$anonymous$$eshFilter>().mesh;
first$$anonymous$$esh.RecalculateBounds();
$$anonymous$$esh second$$anonymous$$esh = firstObject.GetComponent<$$anonymous$$eshFilter>().mesh;
second$$anonymous$$esh.RecalculateBounds();
return first$$anonymous$$esh.bounds.Intersects(second$$anonymous$$esh.bounds);
and with render i just intersect both renderer.bounds
Answer by nikroth · Dec 30, 2013 at 05:13 PM
I have solved the problem in another post of mine. The post -->> The Solved Post
Answer by ThatsAMorais · Dec 17, 2013 at 09:37 PM
Put a "Box Collider" on each Tank
Resize the box collider so that it fits the shape you want
Set each collider to be a Trigger
Create a script which overrides OnTrigger(Collision collision) to detect that an intersection has occurred and between what two entities.
i am not sure how a trigger can be called in another method for checking
Answer by jasonoda · Jun 20, 2014 at 12:09 PM
This has been driving me crazy forever. There are so many situations where you need to do a quick hit test and using onCollision/onTrigger is too hamfisted and bounds doesn't work because of the rotation issue. Here is my solution. Let me know what you think and please improve it as I am not the most efficient coder:
// Test collision between 2 objects without onCollision/onTrigger and from anywhere.
// Solves the rotation inaccuracies that come from trying to achieve this with "bounds.Intersects()" Rotate either object as you wish!
// is probably inefficient. Feel free to improve!
// WARNING: You need to create a level 22 in your Unity editor and have nothing on it for this to work properly
// to test against layer: hitTest(goRef1, null, 8, "box")==1
// to test against other go: hitTest(goRef1, goRef2, 0, "box")==1 - layer is ignored here, put in any number
// RAY can be:
// box: a bounding box measurement. Good for square objects. Recommended in most cases.
// point: 3 lines draw from max/min x,y,z to form a cross in the center. Good for rounder objects.
// hover: Probably nothing you'll need.
function hitTest(go:GameObject, target:GameObject, layer:int, ray:String){
var hit : RaycastHit;
var mode = "layer";
if(target!=null){
layer = target.layer;
mode = "object";
}
//set up directions
var d1 = go.transform.TransformDirection (Vector3.right);
var d2 = go.transform.TransformDirection (Vector3.left);
var d3 = go.transform.TransformDirection (Vector3.up);
var d4 = go.transform.TransformDirection (Vector3.down);
var d5 = go.transform.TransformDirection (Vector3.forward);
var d6 = go.transform.TransformDirection (-Vector3.forward);
//normalize angles to get proper measurements
var saveRot:Vector3 = go.transform.eulerAngles;
go.transform.eulerAngles = Vector3.zero;
var bounds = go.renderer.bounds;
var r1 = new Vector3(bounds.extents.x * d1.x, bounds.extents.x * d1.y, bounds.extents.x * d1.z);
var r2 = new Vector3(bounds.extents.x * d2.x, bounds.extents.x * d2.y, bounds.extents.x * d2.z);
var r3 = new Vector3(bounds.extents.y * d3.x, bounds.extents.y * d3.y, bounds.extents.y * d3.z);
var r4 = new Vector3(bounds.extents.y * d4.x, bounds.extents.y * d4.y, bounds.extents.y * d4.z);
var r5 = new Vector3(bounds.extents.z * d5.x, bounds.extents.z * d5.y, bounds.extents.z * d5.z);
var r6 = new Vector3(bounds.extents.z * d6.x, bounds.extents.z * d6.y, bounds.extents.z * d6.z);
go.transform.eulerAngles = saveRot;
if(ray=="point"){
v1= new Vector3(go.transform.position.x + r1.x,go.transform.position.y + r1.y,go.transform.position.z + r1.z);
v2= new Vector3(go.transform.position.x + r2.x,go.transform.position.y + r2.y,go.transform.position.z + r2.z);
v3= new Vector3(go.transform.position.x + r3.x,go.transform.position.y + r3.y,go.transform.position.z + r3.z);
v4= new Vector3(go.transform.position.x + r4.x,go.transform.position.y + r4.y,go.transform.position.z + r4.z);
v5= new Vector3(go.transform.position.x + r5.x,go.transform.position.y + r5.y,go.transform.position.z + r5.z);
v6= new Vector3(go.transform.position.x + r6.x,go.transform.position.y + r6.y,go.transform.position.z + r6.z);
if(mode=="layer"){
layerMask = 1 << layer;
}else if(mode=="object"){
var saveLayer = go.layer;
target.layer = 22;
layerMask = 1 << 22;
}
if (Physics.Raycast (v1, d2, hit, bounds.extents.x*2, layerMask)) {
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v2, d1, hit, bounds.extents.x*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v3, d4, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v4, d3, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v5, d6, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v6, d5, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}
//none of the raycasts detected anything, but our g.o. could be completely inside the target layer or object which will throw the detection off
//now test to to see if the object is inside
if(checkToSeeIfItsInside(go, layer)==true){
return 1;
}
return 3;
}else if(ray=="box"){
//
v1= new Vector3(go.transform.position.x + r1.x + r3.x + r5.x,go.transform.position.y + r1.y + r3.y + r5.y,go.transform.position.z + r1.z + r3.z + r5.z);
v2= new Vector3(go.transform.position.x + r2.x + r3.x + r5.x,go.transform.position.y + r2.y + r3.y + r5.y,go.transform.position.z + r1.z + r3.z + r5.z);
v3= new Vector3(go.transform.position.x + r2.x + r3.x + r6.x,go.transform.position.y + r2.y + r3.y + r6.y,go.transform.position.z + r2.z + r3.z + r6.z);
v4= new Vector3(go.transform.position.x + r1.x + r3.x + r6.x,go.transform.position.y + r1.y + r3.y + r6.y,go.transform.position.z + r1.z + r3.z + r6.z);
v5= new Vector3(go.transform.position.x + r1.x + r4.x + r5.x,go.transform.position.y + r1.y + r4.y + r5.y,go.transform.position.z + r1.z + r4.z + r5.z);
v6= new Vector3(go.transform.position.x + r2.x + r4.x + r5.x,go.transform.position.y + r2.y + r4.y + r5.y,go.transform.position.z + r2.z + r4.z + r5.z);
v7= new Vector3(go.transform.position.x + r2.x + r4.x + r6.x,go.transform.position.y + r2.y + r4.y + r6.y,go.transform.position.z + r2.z + r4.z + r6.z);
v8= new Vector3(go.transform.position.x + r1.x + r4.x + r6.x,go.transform.position.y + r1.y + r4.y + r6.y,go.transform.position.z + r1.z + r4.z + r6.z);
if(mode=="layer"){
layerMask = 1 << layer;
}else if(mode=="object"){
saveLayer = go.layer;
target.layer = 22;
layerMask = 1 << 22;
}
//down sides
if(Physics.Raycast (v1, d4, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v2, d4, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v3, d4, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v4, d4, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
//up sides
}else if(Physics.Raycast (v5, d3, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v6, d3, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v7, d3, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v8, d3, hit, bounds.extents.y*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
//top
}else if (Physics.Raycast (v1, d2, hit, bounds.extents.x*2, layerMask)) {
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v2, d6, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v3, d1, hit, bounds.extents.x*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v4, d5, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
//bot
}else if(Physics.Raycast (v5, d2, hit, bounds.extents.x*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v6, d6, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v7, d1, hit, bounds.extents.x*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}else if(Physics.Raycast (v8, d5, hit, bounds.extents.z*2, layerMask)){
if(mode=="object"){
target.layer = saveLayer;
}
return 1;
}
if(checkToSeeIfItsInside(go, layer)==true){
return 1;
}
return 3;
}else if(ray=="hover"){
var starts : Array = new Array();;
v1= new Vector3(go.transform.position.x + r1.x,go.transform.position.y + r1.y,go.transform.position.z + r1.z);
v2= new Vector3(go.transform.position.x + r2.x,go.transform.position.y + r2.y,go.transform.position.z + r2.z);
v3= new Vector3(go.transform.position.x + r3.x,go.transform.position.y + r3.y,go.transform.position.z + r3.z);
v4= new Vector3(go.transform.position.x + r4.x,go.transform.position.y + r4.y,go.transform.position.z + r4.z);
v5= new Vector3(go.transform.position.x + r5.x,go.transform.position.y + r5.y,go.transform.position.z + r5.z);
v6= new Vector3(go.transform.position.x + r6.x,go.transform.position.y + r6.y,go.transform.position.z + r6.z);
v7= new Vector3(go.transform.position.x + r1.x + r3.x + r5.x,go.transform.position.y + r1.y + r3.y + r5.y,go.transform.position.z + r1.z + r3.z + r5.z);
v8= new Vector3(go.transform.position.x + r2.x + r3.x + r5.x,go.transform.position.y + r2.y + r3.y + r5.y,go.transform.position.z + r1.z + r3.z + r5.z);
v9= new Vector3(go.transform.position.x + r2.x + r3.x + r6.x,go.transform.position.y + r2.y + r3.y + r6.y,go.transform.position.z + r2.z + r3.z + r6.z);
v10= new Vector3(go.transform.position.x + r1.x + r3.x + r6.x,go.transform.position.y + r1.y + r3.y + r6.y,go.transform.position.z + r1.z + r3.z + r6.z);
v11= new Vector3(go.transform.position.x + r1.x + r4.x + r5.x,go.transform.position.y + r1.y + r4.y + r5.y,go.transform.position.z + r1.z + r4.z + r5.z);
v12= new Vector3(go.transform.position.x + r2.x + r4.x + r5.x,go.transform.position.y + r2.y + r4.y + r5.y,go.transform.position.z + r2.z + r4.z + r5.z);
v13= new Vector3(go.transform.position.x + r2.x + r4.x + r6.x,go.transform.position.y + r2.y + r4.y + r6.y,go.transform.position.z + r2.z + r4.z + r6.z);
v14= new Vector3(go.transform.position.x + r1.x + r4.x + r6.x,go.transform.position.y + r1.y + r4.y + r6.y,go.transform.position.z + r1.z + r4.z + r6.z);
starts.Push(v1);starts.Push(v2);starts.Push(v3);starts.Push(v4);starts.Push(v5);starts.Push(v6);starts.Push(v7);starts.Push(v8);starts.Push(v9);starts.Push(v10);starts.Push(v11);starts.Push(v12);starts.Push(v13);starts.Push(v14);
if(mode=="layer"){
layerMask = 1 << layer;
}else if(mode=="object"){
saveLayer = go.layer;
target.layer = 22;
layerMask = 1 << 22;
}
//down sides
var hits = 0;
for(var sp=0; sp<starts.length; sp++){
starts[sp].y = 600;
if(Physics.Raycast (starts[sp], Vector3.down, hit, 605, layerMask)){
hits++;
}
}
if(mode=="object"){
target.layer = saveLayer;
}
var perc:float = (hits*100)/14;
return perc;
}
}
function checkToSeeIfItsInside(go:GameObject, layer:int){
var hit : RaycastHit;
var all : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
for (var ob : GameObject in all) {
if(ob.layer==layer){
//cycle through all go's in layer
var saveLayer = ob.layer;
ob.layer=22;
//now that everything is out of the way, raycast in all directions to see if the ray only hits the ob
var ac = 1000;
layerMask = 1<<22;
var s1 = new Vector3(go.transform.position.x+ac, go.transform.position.y, go.transform.position.z);
var s2 = new Vector3(go.transform.position.x-ac, go.transform.position.y, go.transform.position.z);
var s3 = new Vector3(go.transform.position.x, go.transform.position.y+ac, go.transform.position.z);
var s4 = new Vector3(go.transform.position.x, go.transform.position.y-ac, go.transform.position.z);
var s5 = new Vector3(go.transform.position.x, go.transform.position.y, go.transform.position.z+ac);
var s6 = new Vector3(go.transform.position.x, go.transform.position.y, go.transform.position.z-ac);
if (Physics.Raycast (s1, Vector3.left, hit, ac*2, layerMask) && Physics.Raycast (s2, Vector3.right, hit, ac*2, layerMask) && Physics.Raycast (s3, Vector3.down, hit, ac*2, layerMask) && Physics.Raycast (s4, Vector3.up, hit, ac*2, layerMask) && Physics.Raycast (s5, -Vector3.forward, hit, ac*2, layerMask) && Physics.Raycast (s6, Vector3.forward, hit, ac*2, layerMask)) {
hasHit=true;
ob.layer=saveLayer;
return true;
}
ob.layer=saveLayer;
}
}
}
Nice job! :-)
I guess this is the biggest code snippet someone has ever posted in an answer. I had to scroll like million times to reach the bottom of this code. ;-)
Wow, man. 380 lines of code. You need to study some trigonometry and math
Your answer
Follow this Question
Related Questions
Determine if two meshes overlap, without using bounds or trigger? 0 Answers
Manipulating vertices through colliders 1 Answer
How would i find the center of an object with a Y axis offset to find the center on the top face? 1 Answer
Collision mesh data problem in Unity WebPlayer 2 Answers
Is there a cheap way to flip a collider´s normals in real time? 0 Answers