How to get all nodes of type MeshInstance3D?

Godot Version

4.4-stable

Question

I have a first-person controller with a RayCast3D scanning for objects. When it collides with a CollisionObject3D it gets the total triangle count of any MeshInstance3D nodes that are direct children of the owner of that particular scene. It works, but only for children. I would like it to find all MeshInstance3D nodes - including grandchildren and others nested ones deep in the scene tree. I’m not sure how to do this.

Here is the player scene tree with the ObjectScanner as the RayCast3D

Here is the code I have so far for the ObjectScanner:

extends RayCast3D

var collider: Object # the CollisionObject3D
var collider_name: String 
var triangle_count: String

func _process(_delta: float) -> void:
	if not enabled:
		return # ensure the RayCast3D is active
		
	collider = get_collider() # get the object the ray cast collided with
	if is_instance_valid(collider) and collider.is_in_group("interactive"):
		get_object_name() # collect name
		get_object_triangle_count() # collect mesh triangle count
	else:
		clear_data() # clear data when no valid collider found
		
func _input(event: InputEvent) -> void:
	# call the object's owner's action() method when clicked
	if is_instance_valid(collider) and collider.is_in_group("interactive"):
		if event.is_action_pressed("interact"):
			var collider_owner = collider.get_owner()
			if collider_owner and collider_owner.has_method("action"):
				collider_owner.action()
				
func get_object_name() -> void: 
	# get the collider's name
	if "object_name" in collider.owner: # check for property
		collider_name = str(collider.owner.object_name)
	
func get_object_triangle_count() -> void: 
	# get the total triangle count of owner's children of type MeshInstance3D 
	# TODO: make the script find nested MeshInstanced3D nodes
	
	var children: Array[Node] = collider.owner.get_children()
	var total_triangles: int = 0 # the sum of all triangles found
	
	for child in children:
		if child is MeshInstance3D and child.mesh:
			var array: PackedVector3Array = child.mesh.get_faces()
			var vertices: int = array.size()
			var triangles: int = int(vertices / 3.0) # matches blender's face count
			total_triangles += triangles
	
	triangle_count = str(total_triangles) if total_triangles > 0 else "no data"
	
func clear_data() -> void:
	collider_name = " "
	triangle_count = "no data"
	
	

If you can help it would be much appreciated. Thank you.

find_children function you can specify a type to find.

1 Like

That points me in a direction to follow. Thank you.

It works. Here is the code that I used for the function:

func get_object_triangle_count() -> void: 
	# get the total triangle count of owner's descendants of type MeshInstance3D 
	
	var total_triangles: int = 0 # the sum of all triangles found
	var mesh_instances: Array[Node] = collider.owner.find_children(
			"", "MeshInstance3D", true, false)

	for node in mesh_instances:
		if node is MeshInstance3D and node.mesh:
			var array: PackedVector3Array = node.mesh.get_faces()
			var vertices: int = array.size()
			var triangles: int = int(vertices / 3.0) # matches blender's face count
			total_triangles += triangles
	
	triangle_count = str(total_triangles) if total_triangles > 0 else "no data"
2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.