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

View file

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

View file

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

View file

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