forked from LGDG/ExampleProject
59 lines
1.7 KiB
GDScript
59 lines
1.7 KiB
GDScript
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)
|