162 lines
3.4 KiB
GDScript
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()
|