Create Player Controller (#4)

* add player scene

* add some logic to control player velocity

* add debug scene and reset main scene

* add sun and env to debug scene; fix normalization of movement

* add kenney WIP assets for debug

* fix movement further and add jump

* add mouse camera control

* add sprinting

* add crouching

* use constants for height

* try to improve crouching by checking to see if there is a collision above before un-crouching

* update README about line width

* move test cube in front of playercontroller
This commit is contained in:
Shea Frembling
2026-02-16 16:33:45 -06:00
committed by GitHub
parent 14cda06d13
commit bab7fe1697
46 changed files with 837 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
extends CharacterBody3D
const JUMP_SPEED: float = 5
const MOUSE_SENSITIVITY: float = 0.002
const CROUCH_MOVE_SPEED: float = 3
const BASE_MOVE_SPEED: float = 5
const SPRINT_MOVE_SPEED: float = 8
const BASE_HEIGHT: float = 2.0
const CROUCH_HEIGHT: float = 1.0
enum MovementMode {
Crouching,
Sprinting,
Walking,
}
var current_movement := MovementMode.Walking
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
var move_speed: float = BASE_MOVE_SPEED
@onready var body_collision_shape: CollisionShape3D = $BodyCollisionShape
@onready var fps_camera: Camera3D = $FPSCamera
@onready var head_collision_shape: CollisionShape3D \
= $HeadCollider/HeadCollisionShape
@onready var head_collider: Area3D = $HeadCollider
func _ready() -> void:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
head_collision_shape.set_deferred("disabled", true)
func _process(delta: float) -> void:
if Input.is_action_just_pressed("pause"):
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
else:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _physics_process(delta: float) -> void:
velocity.y += -gravity * delta
var input = Input.get_vector("strafe_left", "strafe_right",
"move_forward", "move_backward")
if Input.is_action_pressed("sprint") \
and current_movement != MovementMode.Crouching:
move_speed = SPRINT_MOVE_SPEED
current_movement = MovementMode.Sprinting
elif Input.is_action_pressed("crouch") \
and current_movement != MovementMode.Sprinting:
move_speed = CROUCH_MOVE_SPEED
current_movement = MovementMode.Crouching
else:
move_speed = BASE_MOVE_SPEED
current_movement = MovementMode.Walking
if current_movement == MovementMode.Crouching:
body_collision_shape.shape.height = CROUCH_HEIGHT
head_collision_shape.set_deferred("disabled", false)
elif not head_collider.has_overlapping_bodies():
body_collision_shape.shape.height = BASE_HEIGHT
head_collision_shape.set_deferred("disabled", true)
var movement_dir := transform.basis * Vector3(input.x, 0, input.y)
velocity.x = movement_dir.x * move_speed
velocity.z = movement_dir.z * move_speed
move_and_slide()
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = JUMP_SPEED
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion \
and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
fps_camera.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
fps_camera.rotation.x = clampf(fps_camera.rotation.x,
-deg_to_rad(70), deg_to_rad(70))