If you’ve tried baking your lights into a scene you know it’s really quite simple, as long as you have only a few meshes of course, once the scene becomes a complex map composed of many MeshInstances it can be a nightmare to manually make each mesh unique and then unwrap the UVs.
I ran into this problem myself so after a bit of digging in forums and looking for functions I composed them all together and made the following tool script that does it automatically for every single MeshInstace3D in the scene.
It’s not too complex but I’m quite the beginner to godot so It’s a nice feeling to start making my own tools.
@tool
extends Node
@export_category('LightBake')
@export var lightmap_texel_size:float = 0.4
@export var make_unique_and_unwrap: bool = false:
set = _make_unique_and_unwrap
func _make_unique_and_unwrap(new_value: bool) -> void:
make_unique_and_unwrap = false
var all_children: Array = get_all_children(self)
for child: Node in all_children:
if child is MeshInstance3D:
child.mesh = child.mesh.duplicate() #Duplication basically makes the mesh unique
process_uv2(child)
func process_uv2(meshInstance: MeshInstance3D):
var old_mesh = meshInstance.mesh as Mesh
meshInstance.mesh = ArrayMesh.new()
for surface_id in range(old_mesh.get_surface_count()):
meshInstance.mesh.add_surface_from_arrays(
Mesh.PRIMITIVE_TRIANGLES,
old_mesh.surface_get_arrays(surface_id)
)
var old_mat = old_mesh.surface_get_material(surface_id)
meshInstance.mesh.surface_set_material(surface_id, old_mat)
meshInstance.mesh.lightmap_unwrap(global_transform, lightmap_texel_size)
meshInstance.use_in_baked_light = true
func get_all_children(node) -> Array:
var nodes : Array = []
for N in node.get_children():
if N.get_child_count() > 0:
nodes.append(N)
nodes.append_array(get_all_children(N))
else:
nodes.append(N)
return nodes