69 lines
1.9 KiB
GDScript
69 lines
1.9 KiB
GDScript
class_name Player
|
|
extends CharacterBody3D
|
|
|
|
# First-person player controller. WASD relative to body yaw, mouse look
|
|
# (yaw on the body, pitch on the child Camera3D). Jump on space. Gravity
|
|
# is always on — falling into a chasm drops you onto the level below.
|
|
|
|
@export var speed := 6.0
|
|
@export var run_multiplier := 1.8
|
|
@export var jump_velocity := 6.0
|
|
@export var gravity := 22.0
|
|
@export var mouse_sensitivity := 0.002
|
|
|
|
@onready var camera: Camera3D = $Camera3D
|
|
|
|
var _pitch := 0.0
|
|
var _captured := false
|
|
|
|
func _ready() -> void:
|
|
_capture()
|
|
|
|
func _capture() -> void:
|
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
_captured = true
|
|
|
|
func _release() -> void:
|
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
_captured = false
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event is InputEventMouseMotion and _captured:
|
|
var m := event as InputEventMouseMotion
|
|
rotation.y -= m.relative.x * mouse_sensitivity
|
|
_pitch -= m.relative.y * mouse_sensitivity
|
|
_pitch = clamp(_pitch, deg_to_rad(-85.0), deg_to_rad(85.0))
|
|
camera.rotation.x = _pitch
|
|
elif event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
|
|
_release()
|
|
elif event is InputEventMouseButton and event.pressed and not _captured:
|
|
_capture()
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
# Gravity.
|
|
if not is_on_floor():
|
|
velocity.y -= gravity * delta
|
|
|
|
# Horizontal movement relative to yaw.
|
|
var input := Vector2.ZERO
|
|
if Input.is_key_pressed(KEY_W): input.y -= 1.0
|
|
if Input.is_key_pressed(KEY_S): input.y += 1.0
|
|
if Input.is_key_pressed(KEY_A): input.x -= 1.0
|
|
if Input.is_key_pressed(KEY_D): input.x += 1.0
|
|
input = input.normalized()
|
|
|
|
var s := speed
|
|
if Input.is_key_pressed(KEY_SHIFT):
|
|
s *= run_multiplier
|
|
|
|
var forward := -transform.basis.z
|
|
var right := transform.basis.x
|
|
var horiz := (forward * -input.y + right * input.x) * s
|
|
velocity.x = horiz.x
|
|
velocity.z = horiz.z
|
|
|
|
# Jump.
|
|
if is_on_floor() and Input.is_key_pressed(KEY_SPACE):
|
|
velocity.y = jump_velocity
|
|
|
|
move_and_slide()
|