Interaction basics

This commit is contained in:
Rendo 2025-12-19 11:53:44 +05:00
commit 345acc8079
7 changed files with 79 additions and 14 deletions

22
scenes/camera_3d.tscn Normal file
View file

@ -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")

View file

@ -9,6 +9,7 @@ radius = 0.1
height = 0.9921875 height = 0.9921875
[node name="Flask" type="Area3D"] [node name="Flask" type="Area3D"]
collision_layer = 5
script = ExtResource("1_0xufn") script = ExtResource("1_0xufn")
[node name="DragArea" type="CollisionShape3D" parent="."] [node name="DragArea" type="CollisionShape3D" parent="."]

View file

@ -1,6 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://c7r4rhgj3ucao"] [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="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"] [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) transform = Transform3D(2.4088485, 0, 0, 0, 1, 0, 0, 0, 2.8214846, 0, 0, 0)
mesh = SubResource("BoxMesh_cbcd7") mesh = SubResource("BoxMesh_cbcd7")
[node name="Camera3D" type="Camera3D" parent="."] [node name="Camera3D" parent="." instance=ExtResource("1_hflkp")]
transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.5, 0, -0.5, 0.8660253, -1.236948, 2.5364435, 3.1829531) transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.49999994, 0, -0.49999997, 0.8660254, -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="DirectionalLight3D" type="DirectionalLight3D" parent="."] [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) transform = Transform3D(1, 0, 0, 0, 0.8403207, 0.5420896, 0, -0.5420896, 0.8403207, 0, 1.9293891, 0)

View file

@ -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="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="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="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"] [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 radius = 0.22460938
[node name="Flask" type="Area3D"] [node name="Flask" type="Area3D"]
collision_layer = 5
script = ExtResource("1_o7vug") script = ExtResource("1_o7vug")
[node name="Jar" type="MeshInstance3D" parent="."] [node name="Jar" type="MeshInstance3D" parent="."]
@ -30,3 +32,7 @@ shape = SubResource("CylinderShape3D_kfk5m")
[node name="SubstanceData" type="Node" parent="."] [node name="SubstanceData" type="Node" parent="."]
script = ExtResource("7_ymvgp") script = ExtResource("7_ymvgp")
[node name="Interaction" type="ConfirmationDialog" parent="."]
unique_name_in_owner = true
script = ExtResource("5_o7vug")

View file

@ -2,8 +2,10 @@ extends Camera3D
const SENSITIVITY = 0.01 const SENSITIVITY = 0.01
var interaction_source: DraggableObject
var plane_position: Vector3 var plane_position: Vector3
@onready var drag_raycast: RayCast3D = $DragRaycast @onready var drag_raycast: RayCast3D = $DragRaycast
@onready var interaction_area: Area3D = $InteractionArea
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
drag_raycast.target_position = project_local_ray_normal(get_viewport().get_mouse_position()) * 10.0 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: if Input.is_action_pressed("drag_camera") and event is InputEventMouseMotion:
global_position -= Vector3.RIGHT * event.relative.x * SENSITIVITY global_position -= Vector3.RIGHT * event.relative.x * SENSITIVITY
global_position += Vector3.FORWARD * event.relative.y * 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

View file

@ -18,7 +18,6 @@ func _process(_delta: float) -> void:
if dragged == false: if dragged == false:
return return
var camera: Camera3D = get_viewport().get_camera_3d() 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 global_position = camera.plane_position
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
@ -26,6 +25,7 @@ func _input(event: InputEvent) -> void:
if mouse_in and event.pressed: if mouse_in and event.pressed:
dragged = true dragged = true
drag_started.emit() drag_started.emit()
get_viewport().get_camera_3d().interaction_source = self
if event.pressed == false: if event.pressed == false:
dragged = false dragged = false
drag_ended.emit() drag_ended.emit()

View file

@ -1,11 +1,40 @@
extends ConfirmationDialog 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: 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 interact():
func _process(delta: float) -> void: interacted.emit(current_draggable)
pass cleanup()
func cancel_interaction():
cleanup()
func cleanup():
current_draggable = null
current_interaction = null