diff --git a/scenes/camera_3d.tscn b/scenes/camera_3d.tscn new file mode 100644 index 0000000..ee03a43 --- /dev/null +++ b/scenes/camera_3d.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=3 format=3 uid="uid://c2vxq6kqhris0"] + +[ext_resource type="Script" uid="uid://crjao0jjv5yqs" path="res://src/drag/draggable_camera.gd" id="1_v4apc"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hflkp"] +radius = 0.1 +height = 10.5 + +[node name="Camera3D" type="Camera3D"] +transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.5, 0, -0.5, 0.8660253, 0, 0, 0) +script = ExtResource("1_v4apc") + +[node name="DragRaycast" type="RayCast3D" parent="."] +target_position = Vector3(0, 0, -10) + +[node name="InteractionArea" type="Area3D" parent="."] +collision_layer = 0 +collision_mask = 4 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractionArea"] +transform = Transform3D(1, 0, 0, 0, -2.9802322e-08, -1, 0, 1, -2.9802322e-08, 0, 3.5762787e-07, -5.2500005) +shape = SubResource("CapsuleShape3D_hflkp") diff --git a/scenes/flask.tscn b/scenes/flask.tscn index c279371..32ef41d 100644 --- a/scenes/flask.tscn +++ b/scenes/flask.tscn @@ -9,6 +9,7 @@ radius = 0.1 height = 0.9921875 [node name="Flask" type="Area3D"] +collision_layer = 5 script = ExtResource("1_0xufn") [node name="DragArea" type="CollisionShape3D" parent="."] diff --git a/scenes/lab.tscn b/scenes/lab.tscn index 2e94d4b..f8ccd48 100644 --- a/scenes/lab.tscn +++ b/scenes/lab.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=6 format=3 uid="uid://c7r4rhgj3ucao"] -[ext_resource type="Script" uid="uid://crjao0jjv5yqs" path="res://src/drag/draggable_camera.gd" id="1_hem3r"] +[ext_resource type="PackedScene" uid="uid://c2vxq6kqhris0" path="res://scenes/camera_3d.tscn" id="1_hflkp"] [ext_resource type="PackedScene" uid="uid://dfxlr4svnsdyx" path="res://scenes/ui.tscn" id="3_hflkp"] [ext_resource type="Environment" uid="uid://clgblxkcf822n" path="res://assets/Environment.tres" id="8_4kvtl"] @@ -15,12 +15,8 @@ size = Vector3(4, 1, 2) transform = Transform3D(2.4088485, 0, 0, 0, 1, 0, 0, 0, 2.8214846, 0, 0, 0) mesh = SubResource("BoxMesh_cbcd7") -[node name="Camera3D" type="Camera3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.5, 0, -0.5, 0.8660253, -1.236948, 2.5364435, 3.1829531) -script = ExtResource("1_hem3r") - -[node name="DragRaycast" type="RayCast3D" parent="Camera3D"] -target_position = Vector3(0, 0, -10) +[node name="Camera3D" parent="." instance=ExtResource("1_hflkp")] +transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.49999994, 0, -0.49999997, 0.8660254, -1.236948, 2.5364435, 3.1829531) [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.8403207, 0.5420896, 0, -0.5420896, 0.8403207, 0, 1.9293891, 0) diff --git a/scenes/substance_jar.tscn b/scenes/substance_jar.tscn index e6da02d..441dd3f 100644 --- a/scenes/substance_jar.tscn +++ b/scenes/substance_jar.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=7 format=3 uid="uid://cw6v8kbi76qak"] +[gd_scene load_steps=8 format=3 uid="uid://cw6v8kbi76qak"] [ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_o7vug"] [ext_resource type="ArrayMesh" uid="uid://dddqboph2ygmw" path="res://assets/meshes/jar.res" id="2_o7vug"] +[ext_resource type="Script" uid="uid://bl0ojhc0thk1p" path="res://src/interactible/interactible.gd" id="5_o7vug"] [ext_resource type="ArrayMesh" uid="uid://dxeseuqcwne1m" path="res://assets/meshes/jar_fill.res" id="6_kfk5m"] [ext_resource type="Script" uid="uid://c8epd7gguvyop" path="res://src/substance_holder.gd" id="7_ymvgp"] @@ -13,6 +14,7 @@ height = 0.5024414 radius = 0.22460938 [node name="Flask" type="Area3D"] +collision_layer = 5 script = ExtResource("1_o7vug") [node name="Jar" type="MeshInstance3D" parent="."] @@ -30,3 +32,7 @@ shape = SubResource("CylinderShape3D_kfk5m") [node name="SubstanceData" type="Node" parent="."] script = ExtResource("7_ymvgp") + +[node name="Interaction" type="ConfirmationDialog" parent="."] +unique_name_in_owner = true +script = ExtResource("5_o7vug") diff --git a/src/drag/draggable_camera.gd b/src/drag/draggable_camera.gd index 051823e..5f16484 100644 --- a/src/drag/draggable_camera.gd +++ b/src/drag/draggable_camera.gd @@ -2,8 +2,10 @@ extends Camera3D const SENSITIVITY = 0.01 +var interaction_source: DraggableObject var plane_position: Vector3 @onready var drag_raycast: RayCast3D = $DragRaycast +@onready var interaction_area: Area3D = $InteractionArea func _process(_delta: float) -> void: drag_raycast.target_position = project_local_ray_normal(get_viewport().get_mouse_position()) * 10.0 @@ -14,3 +16,12 @@ func _input(event: InputEvent) -> void: if Input.is_action_pressed("drag_camera") and event is InputEventMouseMotion: global_position -= Vector3.RIGHT * event.relative.x * SENSITIVITY global_position += Vector3.FORWARD * event.relative.y * SENSITIVITY + + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: + var areas = interaction_area.get_overlapping_areas() + for area in areas: + if area == interaction_source: + continue + area.try_interact(interaction_source) + break + interaction_source = null diff --git a/src/drag/draggable_object.gd b/src/drag/draggable_object.gd index e698997..c268d29 100644 --- a/src/drag/draggable_object.gd +++ b/src/drag/draggable_object.gd @@ -18,7 +18,6 @@ func _process(_delta: float) -> void: if dragged == false: return var camera: Camera3D = get_viewport().get_camera_3d() - #var new_position: Vector3 = camera.project_position(get_viewport().get_mouse_position(),(-camera.basis.z).dot(camera.to_local(global_position))) global_position = camera.plane_position func _input(event: InputEvent) -> void: @@ -26,6 +25,7 @@ func _input(event: InputEvent) -> void: if mouse_in and event.pressed: dragged = true drag_started.emit() + get_viewport().get_camera_3d().interaction_source = self if event.pressed == false: dragged = false drag_ended.emit() diff --git a/src/interactible/interactible.gd b/src/interactible/interactible.gd index 7c95d06..d606560 100644 --- a/src/interactible/interactible.gd +++ b/src/interactible/interactible.gd @@ -1,11 +1,40 @@ extends ConfirmationDialog +class_name Interactible + +@export var interaction_target_groups: PackedStringArray +@export var instant: bool = false + +var current_draggable: DraggableObject +var current_interaction: Interactible + +signal interacted(with: DraggableObject) -# Called when the node enters the scene tree for the first time. func _ready() -> void: - pass # Replace with function body. + if not instant: + confirmed.connect(interact) + canceled.connect(cancel_interaction) +func try_interact(draggable: DraggableObject) -> void: + if draggable.get_node("%Interaction") != null: + var interaction: Interactible = draggable.get_node("%Interaction") + for group in interaction.get_groups(): + if group in interaction_target_groups: + current_draggable = draggable + current_interaction = interaction + if instant: + interact() + else: + popup_centered() + break -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta: float) -> void: - pass +func interact(): + interacted.emit(current_draggable) + cleanup() + +func cancel_interaction(): + cleanup() + +func cleanup(): + current_draggable = null + current_interaction = null