How to assign procedural mesh to a collider

How do I assign a procedural mesh to a collider? The mesh name that I assign in the script isn't listed in the Mesh drop down until I run the game. At that point I can pause the game, assign the mesh and everything works fine but I can't assign before running.

The code that I'm using now:

gameObject.AddComponent(MeshFilter);
gameObject.AddComponent("MeshRenderer");
gameObject.AddComponent(MeshCollider);

var mesh : Mesh = GetComponent(MeshFilter).mesh;
mesh.name = "terrain1";
GetComponent(MeshCollider).sharedMesh = mesh;  <-- This doesn't work

Assigning a Mesh Collider to a game object procedurally is relatively easy.

This will assign a Mesh Collider to the mesh. Note that this has to be done AFTER you make and apply your mesh, so stick it at the bottom!

// C#
MeshCollider meshc = gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider;

meshc.sharedMesh = terrain1; // Give it your mesh here.

That's it! Unity will calculate and apply your mesh collider here.

What you're trying to do with mesh.name doesn't work. I don't know where you're grabbing "terrain1" from, but here's what you'd do if it were in your project folder. (You'd drag it onto the variable slot. But if you were doing that, I don't see why you wouldn't just add the necessary components in the Editor. Regardless, this is the general idea.)

var terrain1 : Mesh;

(gameObject.AddComponent(MeshFilter) as MeshFilter).mesh = terrain1;
gameObject.AddComponent(MeshRenderer);
gameObject.AddComponent(MeshCollider);

Thanks for your help but I'm still not getting any collisions. I don't think that I can just drag from the project folder because the mesh isn't generated until runtime so there is nothing to drag.

Here's more of the code:

var terrain1 : Mesh; 
(gameObject.AddComponent(MeshFilter) as MeshFilter).mesh = terrain1; 
gameObject.AddComponent(MeshRenderer);
gameObject.AddComponent(MeshCollider); 

// Build vertices and UVs 

........ 

// Assign them to the mesh 

terrain1.vertices = vertices; 
terrain1.uv = uv; 

// Build triangle indices 

........ 

// And assign them to the mesh 

terrain1.triangles = triangles; 
terrain1.RecalculateNormals();

if you procedurally update the mesh collider u need to Null the mesh before assigning the new mesh. i dont know why but i think unity does some optimisation inside.

    GetComponent<MeshCollider>().sharedMesh = null;
    GetComponent<MeshCollider>().sharedMesh = meshFilter.mesh;

that should work

Hi I am having a similar problem with my created meshes too. If I replace them with box colliders they work straight away. I am combining some meshes from single GameObjects together and so creating a new object.

heres my code:

    public GameObject elementObj;
public string modelName = "";
...

this.elementObj = GameObject.Instantiate(Resources.Load("models/"+modelName),Vector3.zero,Quaternion.identity) as GameObject;

this.elementObj.AddComponent<MeshRenderer>();  

Component[] meshFilters = elementObj.GetComponentsInChildren(typeof(MeshFilter));
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
for (int i = 0; i < meshFilters.Length; i++)
{
    combine_.mesh = ((MeshFilter) meshFilters*).sharedMesh;*_
 <em><em>combine_.transform = ((MeshFilter) meshFilters*).transform.localToWorldMatrix;*_</em></em>
<em><em>_*}*_</em></em>
<em><em>_*Component frameBoxMesh = frameBox.GetComponent(typeof(MeshFilter));*_</em></em> 
<em><em>_*((MeshFilter)frameBoxMesh).mesh = new Mesh();*_</em></em>
<em><em>_*((MeshFilter)frameBoxMesh).mesh.CombineMeshes (combine,true,true);*_</em></em>
<em><em>_*MeshCollider frameBoxColl = frameBox.AddComponent(typeof(MeshCollider)) as MeshCollider;*_</em></em>
<em><em>_*frameBoxColl.sharedMesh = null;*_</em></em>
<em><em>_*frameBoxColl.sharedMesh = ((MeshFilter)frameBoxMesh).mesh;*_</em></em>
<em><em>_*```*_</em></em>
<em><em>_*<p>maybe someone else can say why such created meshes are not clickable or why mouse-over does not work.*_</em></em>
<em><em>_*Like mentioned, if I replace the mesh in runtime with a box collider mesh, the scripts work instantly.*_</em></em>
<em><em>_*Do these new created mesh have to be reloaded or something?</p>*_</em></em>

Replace:

var mesh : Mesh = GetComponent(MeshFilter).mesh;  <-- This is actually the issue

By:

var mesh : Mesh = GetComponent(MeshFilter).sharedMesh;

You were trying to get the mesh from MeshFilter. From the docs:

If no mesh is assigned to the mesh filter a new mesh will be created and assigned.
If a mesh is assigned to the mesh filter already, then first query of mesh property will create a duplicate of it, and this copy will be returned. Further queries of mesh property will return this duplicated mesh instance. If you want to avoid this automatic mesh duplication, use MeshFilter.sharedMesh instead.

Have to be very careful with properties that have the shared counter part, such as mesh and material.

Also, as Jessy mentioned, mesh.name = "terrain1"; makes no sense to set the mesh, if that’s what you tried there. So, a complete working solution would be this:

var terrain1 : Mesh;

(gameObject.AddComponent(MeshFilter) as MeshFilter).mesh = terrain1;
gameObject.AddComponent(MeshRenderer);
gameObject.AddComponent(MeshCollider);
 
GetComponent(MeshCollider).sharedMesh = GetComponent(MeshFilter).sharedMesh;