extends Node3D class_name Targetable @export var attached_to: Node3D = owner static func is_targetable(node: Node3D) -> Targetable: return node.get_node_or_null("is_targetable") func make_target(): walk_meshes_post_order(self.get_parent(), change_all_materials) func unmake_target(): walk_meshes_post_order(self.get_parent(), unchange_all_materials) func walk_meshes_post_order(parent: Node3D, f: Callable): for child in parent.get_children(): walk_meshes_post_order(child, f) if parent is MeshInstance3D: f.call(parent) func change_all_materials(mesh: MeshInstance3D): for i in range(mesh.get_surface_override_material_count()): var original_mat: BaseMaterial3D = mesh.get_active_material(i) var layer0 = original_mat.duplicate() var layer1 = preload("control_target_overlay.material").duplicate() # Non-occlused var layer2 = original_mat.duplicate() layer0.next_pass = layer1 layer1.next_pass = layer2 layer0.render_priority = 0 layer1.render_priority = 1 layer2.render_priority = 2 layer0.no_depth_test = true layer0.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS layer0.grow = true layer0.grow_amount = -0.001 layer0.albedo_color = layer0.albedo_color.darkened(0.5) layer2.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS layer2.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_ALWAYS mesh.set_surface_override_material(i, layer0) #mesh.set_surface_override_material(i, mat) #mat.next_pass = preload("control_target_overlay.material") func unchange_all_materials(mesh: MeshInstance3D): for i in range(mesh.get_surface_override_material_count()): var mat := mesh.get_active_material(i) unchange_material(mat) while mat.next_pass != null: unchange_material(mat.next_pass) mat = mat.next_pass mat.next_pass = null func change_material(mat: BaseMaterial3D) -> BaseMaterial3D: mat = mat.duplicate() mat.render_priority = 100 mat.no_depth_test = true return mat func unchange_material(mat: BaseMaterial3D) -> BaseMaterial3D: mat.render_priority = 0 mat.no_depth_test = false return mat