144 lines
4.2 KiB
GDScript
144 lines
4.2 KiB
GDScript
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
|