Skip to content

Instantly share code, notes, and snippets.

@N-Carter
Created August 14, 2024 15:02
Show Gist options
  • Save N-Carter/373b655e9f5c9de4f2c4a4db60c26464 to your computer and use it in GitHub Desktop.
Save N-Carter/373b655e9f5c9de4f2c4a4db60c26464 to your computer and use it in GitHub Desktop.
How to use ArrayMesh.surface_update_vertex_region() in Godot 4
extends MeshInstance3D
@export var _grid_size := 2
# Which of the array of quads to change (must be between 0 and _grid_size * _grid_size):
@export var _quad_to_change := 1
var _array_mesh : ArrayMesh
func _ready() -> void:
_array_mesh = ArrayMesh.new()
var vertices = PackedVector3Array()
# Fill the vertex array with quads arranged in a grid. The quads are made out of two triangles:
for y in _grid_size:
for x in _grid_size:
vertices.append_array(_create_quad_vertices(Vector3(x, y, 0), 0.9))
# Just using the vertex array here for simplicity:
var arrays = []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = vertices
# Calling this function once puts the new surface in index 0, and each subsequent call will
# increase the new surface number by one:
_array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
mesh = _array_mesh
func _process(delta: float) -> void:
# We're going to randomly change the size of one of the quads every frame.
# We have to work out its position again, but that's not part of the example:
var quad_origin := Vector3(_quad_to_change % _grid_size, _quad_to_change / _grid_size, 0.0)
# Make a new set of vertices for that quad:
var new_vertices := _create_quad_vertices(quad_origin, randf() * 0.5)
# Convert it into something which surface_update_vertex_region() will accept:
var byte_array := new_vertices.to_byte_array()
# We have to pass an offset in byte indices, not in vertex indices. We have 6 vertices per
# quad, 3 elements per vertex (x, y, z) and each element is 4 bytes (a float):
var byte_offset := 6 * 3 * 4
# We're editing surface index 0 because that's the only one we have:
_array_mesh.surface_update_vertex_region(0, _quad_to_change * byte_offset, byte_array)
func _create_quad_vertices(origin : Vector3, scale : float) -> PackedVector3Array:
# Create a quad out of two triangles:
var vertices = PackedVector3Array()
vertices.push_back(origin + Vector3(0.0, 0.0, 0.0) * scale)
vertices.push_back(origin + Vector3(0.0, 1.0, 0.0) * scale)
vertices.push_back(origin + Vector3(1.0, 1.0, 0.0) * scale)
vertices.push_back(origin + Vector3(0.0, 0.0, 0.0) * scale)
vertices.push_back(origin + Vector3(1.0, 1.0, 0.0) * scale)
vertices.push_back(origin + Vector3(1.0, 0.0, 0.0) * scale)
return vertices
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment