Mesh collision help

I’ve generated a mesh procedurally and now I want to do collision detection against it. I assume I use the MeshCollider for this.

I have a primitive cube that I’ve turned into a prefab and added a MeshCollider to it and added the mesh I want to test against to the MeshCollider. What I want is to test if my prefab is colliding with the mesh, and if so, with which triangle. But I don’t see anything in the MeshCollider that will let me do this.

Is this the correct approach to do this? If not, then what should I be using?

Ok, I think I figured out what I’m supposed to do, but I can’t seem to detect any collisions.

I gave my procedurally generated mesh a name and confirmed that the correct name is being printed out when I set up my MeshCollider. So I know I have the correct handle to my mesh.

I’m casting a ray from the origin of my primitive in the direction of my primitive’s heading. I’m also drawing that raw using Debug.DrawRay. I can see the ray going through my mesh, but RayCast isn’t detecting any hits.

Is there any other setup of the MeshCollider I need to do? I’m just doing

Update(){
    var mCollider : MeshCollider = transform.GetComponent(MeshCollider);
    var ray : Ray;
    var hit : RaycastHit;
	
	forward = transform.TransformDirection(Vector3.forward);
	forward.Normalize();
	
	ray.origin = transform.position;
	ray.direction = forward;
	
	print(mCollider.sharedMesh.name);
	
    if (mCollider.Raycast (ray, hit, 10)) {
	print("collide");
    }
    Debug.DrawRay(ray.origin, ray.direction*10, Color.red);
}

Does anyone know if, after creating my mesh prcedurally, should it appear in my hierarchy window? Currently, mine doesn’t and I have a feeling this is why collision isn’t working, because when I use Physics.Raycast, I get a hit returned from objects that appear in the hierarchy.

creating a mesh procedurally and adding a mesh collider to it works. I am using it.
How are you creating your mesh?
How are you adding a mesh collider it?
http://unity3d.com/support/documentation/ScriptReference/MeshCollider-sharedMesh.html

I’ve actually gotten a little farther since my last post lol. But I still can’t get MeshCollider to work, although Physics.Raycast seems to work. This is how I generate my mesh

static var meshWall : Mesh;
static var meshWallObj : GameObject;

function Start ()
{
	GenerateWall();
}

function GenerateWall()
{
	meshWallObj = new GameObject();
	
	meshWallObj.tag = "cubeWall";
	
	meshWallObj.AddComponent(MeshFilter);
	meshWallObj.AddComponent("MeshRenderer");
	
	meshWallObj.GetComponent("MeshRenderer").material.color = Color.green;
	meshWallObj.AddComponent(MeshCollider);
	
	meshWall = meshWallObj.GetComponent(MeshFilter).mesh;
	meshWall.name = "cubeWall";
	
	var width = 1;
	var height = 1;
	var x = 0;
	var y = 0;
	
	//6 vertices per face. 6 faces per cube. 4 cubes
	var vertices = new Vector3[6*6*4];
	var uv = new Vector2[6*6*4];
	var tmpv = new Vector3[6*6];
	var tmpuv = new Vector2[6*6];
	var triangles = new int[6*6*4];
	
	var i=0;
	var tmpi;
	var idx = 0;
	var n = 0;
	var sizeScale = Vector3(1,1,1);
	var pos = Vector3(-5, 0, -60);
	
	//gen bottom 2 cubes
	for(n=0;n<2;n++)
	{
		idx=0;
		tmpv = GenerateCube(pos);
		tmpuv = GenerateUVs(tmpv, 6*6);
		tmpi = i + 36;
		for(;i<tmpi;i++)
		{
			vertices[i] =tmpv[idx];
			uv[i] = tmpuv[idx++];
		}
		pos.x+=5;
	}
	
	//gen top 2 cubes
	pos.x-=10;
	pos.y+=5;
	for(n=0;n<2;n++)
	{
		idx=0;
		tmpv = GenerateCube(pos);
		tmpuv = GenerateUVs(tmpv, 6*6);
		tmpi = i + 36;
		for(;i<tmpi;i++)
		{
			vertices[i] =tmpv[idx];
			uv[i] = tmpuv[idx++];
		}
		pos.x+=5;
	}
	
	meshWall.vertices = vertices;
	meshWall.uv = uv;
	
	for(i=0;i<36*4;i=i+1)
	{
		triangles[i] = i;
	}
	meshWall.triangles = triangles;
	meshWall.RecalculateNormals();
}

function GenerateUVs(tris : Vector3[], tlen : int)
{
	var i;
	var uvs = new Vector2[tlen];
	var uvScale = Vector2(1,1);
	
	for(i=0;i<tlen;i=i+1)
	{
		uvs[i] = Vector2.Scale(Vector2 (tris[i].x, tris[i].y), uvScale);
	}
	
	return uvs;
}

function GenerateCube(pos : Vector3)
{
	var tris  = new Vector3[36];
	var cubeSize = 5;
//front face
	//top-left front triangle
	tris[0] = Vector3(pos.x, pos.y, pos.z);
	tris[1] = Vector3(pos.x+cubeSize, pos.y, pos.z);
	tris[2] = Vector3(pos.x, pos.y-cubeSize, pos.z);
	//bottom-right front triangle
	tris[3] = Vector3(pos.x+cubeSize, pos.y, pos.z);
	tris[5] = Vector3(pos.x, pos.y-cubeSize, pos.z);
	tris[4] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z);
//left face
	//top-left left triangle
	tris[6] = Vector3(pos.x, pos.y, pos.z+cubeSize);
	tris[7] = Vector3(pos.x, pos.y, pos.z);
	tris[8] = Vector3(pos.x, pos.y-cubeSize, pos.z+cubeSize);
	//bottom-right left triangle
	tris[9] = Vector3(pos.x, pos.y, pos.z);
	tris[10] = Vector3(pos.x, pos.y-cubeSize, pos.z);
	tris[11] = Vector3(pos.x, pos.y-cubeSize, pos.z+cubeSize);
//back face
	//top-left back triangle
	tris[12] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	tris[13] = Vector3(pos.x, pos.y, pos.z+cubeSize);
	tris[14] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z+cubeSize);
	//bottom-right back triangle
	tris[15] = Vector3(pos.x, pos.y, pos.z+cubeSize);
	tris[16] = Vector3(pos.x, pos.y-cubeSize, pos.z+cubeSize);
	tris[17] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z+cubeSize);
//right face
	//top-left right triangle
	tris[18] = Vector3(pos.x+cubeSize, pos.y, pos.z);
	tris[20] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z);
	tris[19] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z+cubeSize);
	//bottom-right right triangle
	tris[21] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	tris[22] = Vector3(pos.x+cubeSize, pos.y-cubeSize, pos.z+cubeSize);
	tris[23] = Vector3(pos.x+cubeSize, pos.y, pos.z);
//top face
	//top-left top triangle
	tris[24] = Vector3(pos.x, pos.y, pos.z+cubeSize);
	tris[25] = Vector3(pos.x, pos.y, pos.z);
	tris[26] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	//bottom-right top triangle
	tris[27] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	tris[28] = Vector3(pos.x, pos.y, pos.z);
	tris[29] = Vector3(pos.x+cubeSize, pos.y, pos.z);
//bottom face
	//top-left bottom triangle
	tris[30] = Vector3(pos.x, pos.y, pos.z+cubeSize);
	tris[31] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	tris[32] = Vector3(pos.x, pos.y, pos.z);
	//bottom-right bottom triangle
	tris[33] = Vector3(pos.x+cubeSize, pos.y, pos.z+cubeSize);
	tris[34] = Vector3(pos.x+cubeSize, pos.y, pos.z);
	tris[35] = Vector3(pos.x, pos.y, pos.z);
	
	return tris;
}

Then I have a projectile that does a ray cast to see if it collided with the generated mesh.

//#pragma strict

var speed : float;
var lastPos : Vector3;
var posCheck : int;
var startPos : Vector3;

function Start()
{
	var mCollider : MeshCollider;
	
	speed = 5;
	posCheck = 0;
	startPos = transform.position;
	mCollider = cubegen.meshWallObj.GetComponent(MeshCollider) as MeshCollider;
	mCollider.name = "wallCollider";
	
	mCollider.sharedMesh = null;
	mCollider.sharedMesh = cubegen.meshWall;
}

function Update () 
{
	var forward : Vector3;
	var controller : CharacterController = GetComponent(CharacterController) as CharacterController;
	
	var mCollider : MeshCollider = transform.GetComponent(MeshCollider) as MeshCollider;
	var ray : Ray;
    var hit : RaycastHit;
	var meshDir : Vector3;
	
	forward = transform.TransformDirection(Vector3.forward);
	forward.Normalize();
	
	ray.origin = transform.position;
	ray.direction = forward;
	
    if (mCollider.Raycast (ray, hit, 1)) {
        speed = 0;
		print(hit.collider.tag);
    }
	
	Debug.DrawRay(ray.origin, ray.direction*10, Color.red);
	
	controller.Move(forward * speed);
	
	if(posCheck % 10 == 0)
	{
		posCheck = 0;
		var curPos : Vector3 = transform.position;
		var travelDist = Mathf.Sqrt(Mathf.Pow(curPos.x - startPos.x, 2) + Mathf.Pow(curPos.z - startPos.z, 2) + Mathf.Pow(curPos.y - startPos.y, 2));
		if(travelDist > 50)
		{
			Destroy(this.gameObject);
		}
	}
	posCheck = posCheck + 1;
}

function OnCollisionEnter()
{
	print(" OnCollisionEnter");
}

so what doesn’t work? You are able to shoot a ray and hit the collider, no? Are collisions with other objects not registered? Do you have rigidbody attached to at least one of the colliding objects?
I wouldn’t do the mesh collider assignment in the Update. Create the mesh, then assign the collider right after, only once.

One other thing to check is the order of the vertices in the triangles clockwise will be registered by raycasts, anticlockwise won’t. Anticlockwise won’t be visibile also unless you have backface culling to off in the shader.

I was under the impression that the Raycast function was supposed to be called from the MeshCollider object. After all, according to Unity - Scripting API: MeshCollider it is an inherited function. However, it appears that I am supposed to use Physics.Raycast instead. Is that correct? If so, then this is working now.

yes. Physics.Raycast is what you should use.