How do I generate a mesh from code in Godot?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By anonymous

I would like to know how to generate a 3D mesh from code in Godot. I would like to be able to supply a list of vertices, triangles, UVs, etc, and turn this into a Mesh.

In Unity, I can generate custom meshes by using Vector3[] of vertices, Vector2[] of UVs,List<Mesh>, MeshFilter, and CombineInstance. There are many tutorials on how to do this in Unity.

I am using C# but answers in GDscript would also be useful and appreciated (I would expect GDscript answers to be easily translatable to C#)

:bust_in_silhouette: Reply From: path9263

The following code (in GDscript) will apply the generated mesh (a red plane) to a child MeshInstance node named “MeshInstance”

var tmpMesh = Mesh.new()
var vertices = PoolVector3Array()
var UVs = PoolVector2Array()
var mat = SpatialMaterial.new()
var color = Color(0.9, 0.1, 0.1)

func _ready():
	
	vertices.push_back(Vector3(1,0,0))
	vertices.push_back(Vector3(1,0,1))
	vertices.push_back(Vector3(0,0,1))
	vertices.push_back(Vector3(0,0,0))
	
	UVs.push_back(Vector2(0,0))
	UVs.push_back(Vector2(0,1))
	UVs.push_back(Vector2(1,1))
	UVs.push_back(Vector2(1,0))
	
	mat.albedo_color = color
	
	var st = SurfaceTool.new()
	st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN)
	st.set_material(mat)
	
	for v in vertices.size(): 
		st.add_color(color)
		st.add_uv(UVs[v])
		st.add_vertex(vertices[v])
	
	st.commit(tmpMesh)
	
	$MeshInstance.mesh = tmpMesh

It used a Triangle Fan but there are other ways to create your mesh from vertices depending on what order/format you have them stored in. Take a look at the enum PrimitiveTypes on the Mesh page to see your other options.

using that code doesn’t show anything. I am using 3.1.1
No errors
No 3D mesh appearing in the scene

Xian | 2019-06-30 00:43

Did you create a MeshInstance node named “MeshInstance” and is the script adding a mesh to it at runtime? Did you add your MeshInstance to the scene tree?

path9263 | 2019-07-01 06:38

When I try it my plane is black with no color :open_mouth:

And when I edit the size of the plane, lets say from 1 to 5, do I need to adjust the UVs?

AlpacaLord | 2019-07-03 19:54

Did you create a MeshInstance node named "MeshInstance" and is the script adding a mesh to it at runtime? Did you add your MeshInstance to the scene tree? 

yes i did all that. that was 3 days ago and i already got another solution ty

Xian | 2019-07-03 21:44

How did you fix it? Can you share the solution? :slight_smile:

AlpacaLord | 2019-07-04 09:45

I had the same problem. I just have added a Camera node with the following parameters under Spatial > Transform :

  • Translation : 0, 1, 0
  • Rotation : -90, 0, 0

Kurondie | 2019-10-10 18:20

:bust_in_silhouette: Reply From: Barrrettt

You can use SurfaceTool. Simple mehs terrain generator example:

private SurfaceTool createQuad(SurfaceTool st, Vector3 pos, Quat q){

//1Quad = 4 points = 2 triangles
Vector3 v1 = new Vector3(0, q.x,-1) + pos;
Vector3 v2 = new Vector3(1, q.y,-1) + pos;
Vector3 v3 = new Vector3(1, q.w, 0) + pos;
Vector3 v4 = new Vector3(0, q.z,0) + pos;
//tri1
st.AddUv(new Vector2(0,0));
st.AddColor(heightToColor(v1.y));// active albedoVertexColors
st.AddVertex(v1);


st.AddUv(new Vector2(0,1));
st.AddColor(heightToColor(v2.y));
st.AddVertex(v2);


st.AddUv(new Vector2(1,1));
st.AddColor(heightToColor(v4.y));
st.AddVertex(v4);

//tri2
st.AddUv(new Vector2(0,0));
st.AddColor(heightToColor(v2.y));
st.AddVertex(v2);

st.AddUv(new Vector2(0,1));
st.AddColor(heightToColor(v3.y));
st.AddVertex(v3);

st.AddUv(new Vector2(1,1));
st.AddColor(heightToColor(v4.y));
st.AddVertex(v4);

return st;

}

Watched this video before but forgot about it. I can’t create a mesh. I tried it on the internet, but it just isn’t visible.

extends Node2D

var tmpMesh = Mesh.new()
var vertices = PoolVector3Array()
var UVs = PoolVector2Array()
var mat = SpatialMaterial.new()
var color = Color(0.9, 0.1, 0.1)

func _ready():

	vertices.push_back(Vector3(1,0,0))
	vertices.push_back(Vector3(1,0,1))
	vertices.push_back(Vector3(0,0,1))
	vertices.push_back(Vector3(0,0,0))

    UVs.push_back(Vector2(0,0))
	UVs.push_back(Vector2(0,1))
	UVs.push_back(Vector2(1,1))
    UVs.push_back(Vector2(1,0))

	mat.albedo_color = color

	var st = SurfaceTool.new()
	st.begin(Mesh.PRIMITIVE_TRIANGLE_FAN)
	st.set_material(mat)

	for v in vertices.size(): 
    	st.add_color(color)
    	st.add_uv(UVs[v])
    	st.add_vertex(vertices[v])

	st.commit(tmpMesh)

	$MeshInstance2D.mesh = tmpMesh

Timofey | 2021-06-02 17:55

I tried to do it in 2D at first, because I thought that I was pointing the camera in the wrong direction.

Timofey | 2021-06-02 17:56