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.