58 lines
1.6 KiB
GDScript
58 lines
1.6 KiB
GDScript
class_name EntityInteractor extends Node
|
|
|
|
enum InteractorType {
|
|
PLAYER_INPUT,
|
|
UNDECIDED
|
|
}
|
|
|
|
@export var interactorType:InteractorType = InteractorType.UNDECIDED;
|
|
@export var entityDirection:EntityDirection = null;
|
|
@export var characterBody:CharacterBody3D = null;
|
|
@export var interactRange = 0.7;
|
|
@export var entity:Entity = null
|
|
@export_flags_3d_physics() var interactLayers = 2;
|
|
|
|
func interactWith(interactable:EntityInteractable) -> void:
|
|
interactable.interact(self)
|
|
|
|
func getRaycastInteractable() -> EntityInteractable:
|
|
if !entityDirection or !characterBody:
|
|
return null
|
|
|
|
var rayDirection = entityDirection.getDirectionVector()
|
|
var query = PhysicsRayQueryParameters3D.create(
|
|
characterBody.position,
|
|
characterBody.position + (rayDirection * interactRange)
|
|
)
|
|
query.collide_with_bodies = true;
|
|
query.collide_with_areas = true;
|
|
query.collision_mask = interactLayers;
|
|
query.exclude = [ characterBody ];
|
|
|
|
var result = characterBody.get_world_3d().direct_space_state.intersect_ray(query)
|
|
if !result or !result.collider:
|
|
return null
|
|
|
|
var coll:Node3D = result.collider;
|
|
var interactable:EntityInteractable = coll.find_child("EntityInteractable")
|
|
return interactable
|
|
|
|
func _process(delta: float) -> void:
|
|
match interactorType:
|
|
InteractorType.PLAYER_INPUT:
|
|
_processPlayerInput()
|
|
InteractorType.UNDECIDED:
|
|
_processUndecided()
|
|
_:
|
|
assert(false, "Invalid interactor type")
|
|
|
|
func _processPlayerInput() -> void:
|
|
if !Input.is_action_just_pressed("interact"):
|
|
return
|
|
|
|
var interactable:EntityInteractable = getRaycastInteractable()
|
|
if interactable:
|
|
self.interactWith(interactable)
|
|
|
|
func _processUndecided() -> void:
|
|
pass |