Interaction rework
This commit is contained in:
parent
345acc8079
commit
72bea66082
11 changed files with 90 additions and 23 deletions
|
|
@ -1,11 +1,13 @@
|
|||
extends Camera3D
|
||||
|
||||
class_name DraggableCamera
|
||||
|
||||
const SENSITIVITY = 0.01
|
||||
|
||||
var interaction_source: DraggableObject
|
||||
var plane_position: Vector3
|
||||
@onready var drag_raycast: RayCast3D = $DragRaycast
|
||||
@onready var interaction_area: Area3D = $InteractionArea
|
||||
@onready var interaction_area: InteractibleDetector = $InteractionArea
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
drag_raycast.target_position = project_local_ray_normal(get_viewport().get_mouse_position()) * 10.0
|
||||
|
|
@ -18,10 +20,21 @@ func _input(event: InputEvent) -> void:
|
|||
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:
|
||||
for draggable in interaction_area.filtered_draggables:
|
||||
if draggable == interaction_source:
|
||||
continue
|
||||
area.try_interact(interaction_source)
|
||||
interaction_source.interactible.try_interact(draggable)
|
||||
break
|
||||
interaction_source = null
|
||||
end_interaction_seeking()
|
||||
|
||||
func start_interaction_seeking(new_interaction_source: DraggableObject) -> void:
|
||||
if new_interaction_source.interactible == null:
|
||||
return
|
||||
interaction_source = new_interaction_source
|
||||
interaction_area.set_mask(interaction_source.interactible.get_groups())
|
||||
|
||||
func end_interaction_seeking() -> void:
|
||||
if interaction_source == null:
|
||||
return
|
||||
|
||||
interaction_source = null
|
||||
|
|
|
|||
|
|
@ -6,7 +6,17 @@ signal drag_started
|
|||
signal drag_ended
|
||||
|
||||
var mouse_in: bool = false
|
||||
var dragged: bool = false
|
||||
var dragged: bool = false:
|
||||
set(value):
|
||||
if dragged != value:
|
||||
if value:
|
||||
drag_started.emit()
|
||||
get_viewport().get_camera_3d().start_interaction_seeking(self)
|
||||
else:
|
||||
drag_ended.emit()
|
||||
dragged = value
|
||||
|
||||
@export var interactible: Interactible
|
||||
|
||||
func _mouse_enter() -> void:
|
||||
mouse_in = true
|
||||
|
|
@ -24,8 +34,5 @@ func _input(event: InputEvent) -> void:
|
|||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ func _ready() -> void:
|
|||
canceled.connect(cancel_interaction)
|
||||
|
||||
func try_interact(draggable: DraggableObject) -> void:
|
||||
if draggable.get_node("%Interaction") != null:
|
||||
var interaction: Interactible = draggable.get_node("%Interaction")
|
||||
if draggable.interactible != null:
|
||||
var interaction: Interactible = draggable.interactible
|
||||
for group in interaction.get_groups():
|
||||
if group in interaction_target_groups:
|
||||
current_draggable = draggable
|
||||
|
|
|
|||
37
src/interactible/interactible_detector.gd
Normal file
37
src/interactible/interactible_detector.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
extends Area3D
|
||||
|
||||
class_name InteractibleDetector
|
||||
|
||||
var mask: PackedStringArray
|
||||
var contacted_draggables: Array[DraggableObject]
|
||||
var filtered_draggables: Array[DraggableObject]
|
||||
|
||||
func set_mask(new_mask: PackedStringArray) -> void:
|
||||
mask.clear()
|
||||
mask.append_array(new_mask)
|
||||
filtered_draggables.clear()
|
||||
for contacted in contacted_draggables:
|
||||
filtered_draggables.append(contacted)
|
||||
|
||||
func _ready() -> void:
|
||||
area_entered.connect(on_area_entered)
|
||||
area_exited.connect(on_area_exited)
|
||||
|
||||
func on_area_entered(area: Area3D) -> void:
|
||||
if area is DraggableObject:
|
||||
contacted_draggables.append(area)
|
||||
if is_in_mask(area.get_groups()):
|
||||
filtered_draggables.append(area)
|
||||
|
||||
func on_area_exited(area: Area3D) -> void:
|
||||
if area is DraggableObject:
|
||||
contacted_draggables.erase(area)
|
||||
if filtered_draggables.has(area):
|
||||
filtered_draggables.erase(area)
|
||||
|
||||
func is_in_mask(groups: Array[StringName]) -> bool:
|
||||
for group in groups:
|
||||
if group in mask:
|
||||
return true
|
||||
return false
|
||||
|
||||
1
src/interactible/interactible_detector.gd.uid
Normal file
1
src/interactible/interactible_detector.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://d77lra3ar60b
|
||||
|
|
@ -5,9 +5,9 @@ extends Button
|
|||
|
||||
func _on_button_down() -> void:
|
||||
var scene = draggable.scene_to_spawn.instantiate()
|
||||
get_tree().current_scene.add_child(scene)
|
||||
if scene is DraggableObject:
|
||||
scene.dragged = true
|
||||
scene.mouse_in = true
|
||||
get_tree().current_scene.add_child(scene)
|
||||
var camera = get_viewport().get_camera_3d()
|
||||
scene.global_position = camera.project_position(get_global_mouse_position(),1.8)
|
||||
scene.global_position = camera.plane_position
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ func _ready() -> void:
|
|||
|
||||
func _on_button_down() -> void:
|
||||
var scene = reagent.storage.instantiate()
|
||||
|
||||
scene.get_node("SubstanceData").substance = reagent.substance
|
||||
get_tree().current_scene.add_child(scene)
|
||||
if scene is DraggableObject:
|
||||
scene.dragged = true
|
||||
scene.mouse_in = true
|
||||
scene.get_node("SubstanceData").substance = reagent.substance
|
||||
get_tree().current_scene.add_child(scene)
|
||||
var camera = get_viewport().get_camera_3d()
|
||||
scene.global_position = camera.project_position(get_global_mouse_position(),1.8)
|
||||
scene.global_position = camera.plane_position
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue