There’s a few different ways to assign specific materials to an FBX or glTF object in Godot 4.5.2 (and presumably newer).
- You can simply make the object “local”, then you can go through and assign each surface override like so:
var _mat = load(MatSet[Mat0])
$Spectre/SM_SpectreEngines_00/SM_SpectreEngines_00a.set_surface_override_material(0, _mat)
$Spectre/SM_SpectreEngines_00/SM_SpectreEngines_00b.set_surface_override_material(0, _mat)
... etc
This definitely works if you already had to make the mesh local for some other reason, but it’ll explode the size of your TSCN and drastically increase load time:
13M May 31 21:46 ./Spectre_light.tscn
# vs
1.9K Jun 6 20:28 ./Spectre_light.tscn
-
You can also use that same explicit method while switching to a binary .scn file to reduce size, but at the cost of reducing git effectiveness and readability.
-
Alternatively, you can use the exact same explicit method, but not make the mesh local, which is still very manual but dramatically reduces load time.
-
However, the method I stumbled across through experimentation that I find far better is this one:
func _setColor():
# We load and call it because it has a recursive
var _mat = load(ShipData.SmallBodies[shipSpecific]["mats"][Mat0])
apply_overrides($Spectre, _mat)
pass
# This is SO MUCH simpler than the other methods I've found
# Just build the override map from the FBX, as it's seen by Godot
func apply_overrides(_node, _mat):
var override_map = {
"Exterior": _mat,
#"Glass": load("res://mat_glass.tres"),
#"Interior": load("res://mat_interior.tres")
}
if _node is MeshInstance3D:
var mesh = _node.mesh
if mesh:
for i in mesh.get_surface_count():
var surf_name = mesh.surface_get_name(i)
if override_map.has(surf_name):
_node.set_surface_override_material(i, override_map[surf_name])
for child in _node.get_children():
apply_overrides(child, _mat)
So here what we do is just grab the materials as seen in the import wizard:
Then you can override them for the whole mesh very easily just like you would from the importer. The function loops over each item in the FBX/glTF tree, grabs, the meshes, matches the name, and then applies the new material.
It reduces loading time, disk space, and complexity.
