Godot interaction system init
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
@export var speed: float = 6.0
|
||||
@export var jumpVelocity: float = 5.0
|
||||
@export var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") as float
|
||||
|
||||
@export var acceleration: float = 20.0
|
||||
@export var airAcceleration: float = 4.0
|
||||
@export var friction: float = 10.0
|
||||
|
||||
var mouseBaseSensitivity: float = 0.004
|
||||
var mouseSensitivity: float = 0.0
|
||||
@export var mouseSensitivityMultiplier: float = 0.2
|
||||
|
||||
@export var head: Node3D
|
||||
@export var camera: Camera3D
|
||||
@export var raycast: RayCast3D
|
||||
@export var hand: Marker3D
|
||||
@export var crosshair: CanvasLayer
|
||||
|
||||
var lateJumpTime: float = 0.15
|
||||
var lateJumpTimer: float = 0.0
|
||||
|
||||
var currentInteractable: Interactable
|
||||
var dragging: bool = false
|
||||
|
||||
var pitch: float = 0.0
|
||||
|
||||
var playerId: String
|
||||
var displayName: String
|
||||
|
||||
var mouseDelta: Vector2 = Vector2.ZERO
|
||||
var interactionMouseDelta: Vector2 = Vector2.ZERO
|
||||
|
||||
var mouseHorizontalFactor: float = 1.0
|
||||
var mouseVerticalFactor: float = 1.0
|
||||
|
||||
var targetMouseHorizontalFactor: float = 1.0
|
||||
var targetMouseVerticalFactor: float = 1.0
|
||||
@export var mouseFactorLerpSpeed: float = 2.0
|
||||
|
||||
func _ready():
|
||||
mouseSensitivity = mouseBaseSensitivity * mouseSensitivityMultiplier
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
else:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED:
|
||||
return
|
||||
|
||||
if event is InputEventMouseMotion:
|
||||
if dragging and currentInteractable:
|
||||
interactionMouseDelta += event.relative
|
||||
mouseDelta += event.relative
|
||||
|
||||
func _physics_process(delta):
|
||||
mouseHorizontalFactor = lerp(mouseHorizontalFactor, targetMouseHorizontalFactor, delta * mouseFactorLerpSpeed)
|
||||
mouseVerticalFactor = lerp(mouseVerticalFactor, targetMouseVerticalFactor, delta * mouseFactorLerpSpeed)
|
||||
|
||||
if mouseDelta != Vector2.ZERO:
|
||||
rotate_y(-mouseDelta.x * mouseSensitivity * mouseHorizontalFactor)
|
||||
|
||||
pitch -= mouseDelta.y * mouseSensitivity * mouseVerticalFactor
|
||||
pitch = clamp(pitch, deg_to_rad(-90), deg_to_rad(90))
|
||||
head.rotation.x = pitch
|
||||
|
||||
mouseDelta = Vector2.ZERO
|
||||
|
||||
if !is_on_floor():
|
||||
velocity.y -= gravity * delta
|
||||
lateJumpTimer -= delta
|
||||
else:
|
||||
lateJumpTimer = lateJumpTime
|
||||
|
||||
# Interaction search
|
||||
if !dragging:
|
||||
if raycast.is_colliding():
|
||||
currentInteractable = Interactable.find(raycast.get_collider())
|
||||
crosshair.setHover(true)
|
||||
else:
|
||||
currentInteractable = null
|
||||
crosshair.setHover(false)
|
||||
|
||||
# Start interaction
|
||||
if !dragging and currentInteractable:
|
||||
if Input.is_action_just_pressed("interact"):
|
||||
dragging = true
|
||||
currentInteractable.beginInteract(self, raycast.get_collision_point())
|
||||
|
||||
# Update interaction
|
||||
if dragging and currentInteractable:
|
||||
if Input.is_action_just_pressed("throw"):
|
||||
if currentInteractable is Pickupable:
|
||||
currentInteractable.throw()
|
||||
stopInteraction()
|
||||
return
|
||||
|
||||
currentInteractable.updateInteract(self)
|
||||
interactionMouseDelta = Vector2.ZERO
|
||||
|
||||
# End interaction
|
||||
if dragging and currentInteractable:
|
||||
if Input.is_action_just_released("interact"):
|
||||
stopInteraction()
|
||||
|
||||
# Late jump buffering
|
||||
if Input.is_action_just_pressed("jump") and lateJumpTimer > 0.0:
|
||||
velocity.y = jumpVelocity
|
||||
|
||||
# Movement
|
||||
var inputDir := Input.get_vector("left", "right", "forward", "backward")
|
||||
var direction := (transform.basis * Vector3(inputDir.x, 0, inputDir.y)).normalized()
|
||||
|
||||
if is_on_floor():
|
||||
if direction != Vector3.ZERO:
|
||||
velocity.x = direction.x * speed
|
||||
velocity.z = direction.z * speed
|
||||
else:
|
||||
velocity.x = lerp(velocity.x, 0.0, delta * friction)
|
||||
velocity.z = lerp(velocity.z, 0.0, delta * friction)
|
||||
else:
|
||||
velocity.x = lerp(velocity.x, direction.x * speed, delta * airAcceleration)
|
||||
velocity.z = lerp(velocity.z, direction.z * speed, delta * airAcceleration)
|
||||
|
||||
move_and_slide()
|
||||
|
||||
func setMouseFactors(horizontal: float, vertical: float):
|
||||
targetMouseHorizontalFactor = clamp(horizontal, 0.0, 1.0)
|
||||
targetMouseVerticalFactor = clamp(vertical, 0.0, 1.0)
|
||||
|
||||
func stopInteraction():
|
||||
if currentInteractable:
|
||||
currentInteractable.endInteract(self)
|
||||
|
||||
currentInteractable = null
|
||||
dragging = false
|
||||
interactionMouseDelta = Vector2.ZERO
|
||||
Reference in New Issue
Block a user