Files
Scavenger-2027/Objects/Player/controller.gd
T
2026-09-10 07:47:15 -04:00

162 lines
3.4 KiB
GDScript

extends CharacterBody3D
# Acceleration and deceleration are m/s².
# max_speed is m/s.
@export var accel := 6.7
@export var deccel := 8.5
@export var max_speed := 6.2
@export var has_suit := true
@export var has_hvms2 := true
@export var gravity := 9.8
@export var jump_velocity := 4.5
# Mouse sensitivity
@export var mouse_sensitivity := 0.003
# Maximum camera pitch in degrees
@export var max_pitch := 89.0
var movement_vec := Vector3.ZERO
var input_vec := Vector4.ZERO
var jump := false
var air_jumps := 0
func _ready() -> void:
if not has_suit:
$yaw/pitch/Camera/Hud.visible = false
if has_hvms2:
max_speed = 30.0
accel = 10
deccel = 20
jump_velocity = 10
# Capture the mouse when the game starts
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _input(event: InputEvent) -> void:
# Mouse-look
if event is InputEventMouseMotion:
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
# Horizontal rotation: rotate the player
$yaw.rotate_y(-event.relative.x * mouse_sensitivity)
# Vertical rotation: rotate the camera
$yaw/pitch.rotate_x(-event.relative.y * mouse_sensitivity)
# Clamp pitch so the camera cannot flip upside down
$yaw/pitch.rotation.x = clamp(
$yaw/pitch.rotation.x,
deg_to_rad(-max_pitch),
deg_to_rad(max_pitch)
)
return
# Mouse click captures the mouse again
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
return
# Keyboard input
if event is InputEventKey:
var pressed: bool = event.pressed
match event.keycode:
KEY_W:
input_vec.w = 1.0 if pressed else 0.0
KEY_S:
input_vec.x = 1.0 if pressed else 0.0
KEY_A:
input_vec.y = 1.0 if pressed else 0.0
KEY_D:
input_vec.z = 1.0 if pressed else 0.0
KEY_SPACE:
if pressed and is_on_floor():
jump=true
KEY_ESCAPE:
if pressed:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
KEY_SHIFT:
if has_hvms2:
velocity.y = max(velocity.y, -3) if pressed else velocity.y
gravity = 3 if pressed else 9.8
if is_on_floor():
velocity=$yaw/pitch/Camera.basis*Vector3(0,0,50)
func _physics_process(delta: float) -> void:
# W/S/A/D input
var input_direction := Vector2(
input_vec.z - input_vec.y,
input_vec.w - input_vec.x
)
if input_direction.length() > 1.0:
input_direction = input_direction.normalized()
# Camera yaw only
var yaw_basis: Basis = $yaw.global_transform.basis
var forward := -yaw_basis.z
var right := yaw_basis.x
forward.y = 0.0
right.y = 0.0
forward = forward.normalized()
right = right.normalized()
var target_direction := (
right * input_direction.x
+ forward * input_direction.y
)
# Target horizontal velocity in m/s
var target_velocity := target_direction * max_speed
# Current horizontal velocity in m/s
var current_velocity := Vector3(
velocity.x,
0.0,
velocity.z
)
# Acceleration/deceleration in m/s²
var acceleration := accel if target_direction != Vector3.ZERO else deccel
current_velocity = current_velocity.move_toward(
target_velocity,
acceleration * delta
)
velocity.x = current_velocity.x
velocity.z = current_velocity.z
# Gravity
if not is_on_floor():
velocity.y -= gravity * delta
else:
if jump:
velocity.y=jump_velocity
jump=false
else:
velocity.y=0.0
if global_position.y<=-1000:
get_tree().reload_current_scene()
move_and_slide()