1
0
Fork 0
ExampleProject/InteractiveItems.gd

59 lines
1.7 KiB
GDScript3
Raw Permalink Normal View History

2024-03-14 11:50:53 +00:00
extends Node
class_name InteractiveItems
# Emits the node with the `item_group_name` group set.
signal item_clicked(node: Node)
@export var item_group_name: String = "item"
@export var call_interact: bool = true
@export var show_debug_label: bool = true
var label
var current_object
func find_interactive():
return get_tree().get_nodes_in_group(item_group_name)
func list_nodes(node: Node, parent: bool = true) -> Array[Node]:
var res: Array[Node] = [node]
if parent and node.get_parent(): res.append(node.get_parent())
res.append_array(node.get_children())
return res
func get_collision(mesh: MeshInstance3D) -> CollisionObject3D:
for node in list_nodes(mesh):
if node is CollisionObject3D: return node
mesh.create_convex_collision()
return mesh.get_child(mesh.get_child_count() - 1)
func _on_mouse_entered(node: Node3D, entered: bool):
current_object = node if entered else null
if label: label.text = node.name if entered else &""
func do_interact(node: Node):
for child in list_nodes(node, false):
if child.has_method("interact"):
child.call("interact")
return
func setup_label():
if not show_debug_label: return
label = Label.new()
label.position = Vector2(20, 20)
add_child(label)
func _ready():
setup_label()
for item in find_interactive():
var col := get_collision(item)
col.input_ray_pickable = true # make sure Input.Ray Pickable is Off for invisible walls
col.connect("mouse_entered", _on_mouse_entered.bind(item, true))
col.connect("mouse_exited", _on_mouse_entered.bind(item, false))
func _unhandled_input(event):
if event.is_action_pressed("ui_accept"):
if current_object:
#print(current_object)
if call_interact: do_interact(current_object)
item_clicked.emit(current_object)