Yes, you can change a mesh at runtime.
- get the current mesh from your object using
Mesh mesh = GetComponent<MeshFilter>().mesh
. Alternatively, if you want to replace the mesh with a completely new one, create one withMesh mesh = new Mesh();
and assign it to your object withGetComponent<MeshFilter>().mesh = mesh;
- When you intend to modify the same mesh every frame, you should call the
MarkDynamic()
method on it. This might improve performance in that situation (thanks, Kroltan). - Modify the
Mesh
object. It is a reference-type, so any changes you make will be reflected by the object which owns the mesh. For a minimum functional mesh you need to set at least its.vertices
and.triangles
component, if you want it to be textured also theuv
component. If you are really just going to change the positions of vertices of an existing mesh, then the.vertices
property is likely the only one you need. But keep in mind that you have little control over the order in which your 3d modeling program saves the vertices of a 3d model, so a slight change to the model can mean that the indexes of all vertices change in a completely unpredictable way. - When you are finished, call
mesh.RecalculateNormals
which is required by almost every shader to calculate brightness levels correctly. - The
.tangents
component is also important for some shaders, especially those which use bump mapping. The documentation warns that it needs to be set after you updated the normals. - If you use that mesh for a MeshCollider, you should also call
mesh.RecalculateBounds
. You mentioned you are doing collision detection all by yourself, so this might not be necessary in your case, but it might be necessary for other people.
Unity also made an example of procedural mesh generation as a complete project on the asset store available for free.
Will it be fast enough for mobile phones? That depends on countless factors, like what kind of mobile phone you are talking about, how often you are going to change the mesh, how effective your mesh changing algorithm is, what shaders you are using and much more. You need to test it for yourself. By the way, if your changes will usually be localized, it might help to break down your terrain into multiple sub-objects and only update the meshes of those which were affected.