extends Node3D
var material_overrides:Resource = preload("res://scripts/material_overrides.gd")
func _ready() -> void:
for x in get_child_count():
for y in get_child(x).get_children():
if y.get_class() == "MeshInstance3D":
y.set_script(material_overrides)
material_overrides.gd:
extends MeshInstance3D
var material_overrides:Dictionary = {
"metal_plate": {"metallic": 1.0},
"wet_brick": {"roughness": 0.3},
}
func _init() -> void:
var surface_name:String = mesh.get("surface_0/name")
apply_override(surface_name)
func apply_override(surface_name:String) -> void:
if material_overrides.has(surface_name):
var properties:Dictionary = material_overrides[surface_name]
var material:Material = mesh.surface_get_material(0)
for p:String in properties:
material.set(p, properties[p])
Don’t really like 3 nested loops, but hey, at least this code is only run once when the tree is ready, so it should not be that big of a deal.
But anyway, is there any better way to reference a specific child node by it’s type?
This feels a bit unintuitive, but it’s hard to point out why since I’m not sure why you’re changing the values/what you are trying to achieve.
But generally I would advise against using set_script. There are much cleaner solutions.
You could use Godot’s Group system to get the relevant nodes and then modify them from one script. I would also prefer to create a completely new material with the options you want to use e.g. wet_brick_material.tres
const wet_brick_mat := preload("res://web_brick_material.tres")
func change_materials():
var nodes := get_tree().get_nodes_in_group("change_material")
for node in nodes:
node.material = wet_brick_mat
If you don’t want to explicitly Group them for material change then your way of getting the node references if fine, though it could be made more “general”. Choose a starting node and then recursively fetch it’s children, add the meshes to an array, then fetch the children of those and add the meshes, etc. until there are no more children
The nested loops are necessary if you want to recursively look for children It’s not a problem. Avoiding nested loops is a good principle but they are also often necessary, it’s just that they should be avoided if and when a better solution also exists