How do I set the mesh dynamically in Godot3?

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

I have done a procedural triangle by creating and instancing a meshinstance dynamically (using a script that extends Spatial), but now I want to have the constructed geometry remaining in the editor. So first I tried adding a MeshInstance statically, then attaching it a script which builds a triangle on _ready(), but I don’t see any triangle yet in the editor (the triangle shows up then I run the code, as expected). I am guessing that _ready() is not the proper call function for my intent, but I don’t know what to use.

Here is the code:

extends MeshInstance

func _ready():
    var size = 10
    var st = SurfaceTool.new()
    var mat = SpatialMaterial.new()
    mat.albedo_color = Color(1.0, 0.0, 0.0)
    st.set_material(mat)
    st.begin(Mesh.PRIMITIVE_TRIANGLES)
    st.add_uv(Vector2(0, 0))
    st.add_vertex(Vector3(-size, -size,  0))
    st.add_uv(Vector2(1, 1))
    st.add_vertex(Vector3( size,  size,  0))
    st.add_uv(Vector2(1, 0))
    st.add_vertex(Vector3( size, -size,  0))
    st.generate_normals()
    var mesh = st.commit()
    self.set_mesh(mesh)

Update: I tried the keywork tool at the top of the script as suggested in the docs. Nope.

:bust_in_silhouette: Reply From: grok

I managed to solve it, the editor behaved weird, then freezed and once I restarted it it worked. I also had to set the material after the surface tool begin() method. If anyone wants this here is the full code.

tool
extends MeshInstance

func _ready():
	var size = 10
	var st = SurfaceTool.new()
	var mat = SpatialMaterial.new()
	mat.albedo_color = Color(1.0, 0.0, 0.0)
	
	st.begin(Mesh.PRIMITIVE_TRIANGLES)
	st.set_material(mat)
	st.add_uv(Vector2(0, 0))
	st.add_vertex(Vector3(-size, -size,  0))
	st.add_uv(Vector2(1, 1))
	st.add_vertex(Vector3( size,  size,  0))
	st.add_uv(Vector2(1, 0))
	st.add_vertex(Vector3( size, -size,  0))
	st.generate_normals()
	var mesh = st.commit()
	self.set_mesh(mesh)