From 0a9f384bcf2e68c6dcad937c62a77f512627195b Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Thu, 6 Mar 2025 15:31:48 -0500 Subject: [PATCH] Adding running and crouching --- project.godot | 5 ++++ scenes/player/player.gd | 52 +++++++++++++++++++++++++++++++-------- scenes/player/player.tscn | 22 ++++++++++++++--- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/project.godot b/project.godot index 42fd75a..f06f268 100644 --- a/project.godot +++ b/project.godot @@ -98,6 +98,11 @@ run={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +crouch={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/scenes/player/player.gd b/scenes/player/player.gd index 20b7ea3..92f5929 100644 --- a/scenes/player/player.gd +++ b/scenes/player/player.gd @@ -2,24 +2,34 @@ class_name Player extends CharacterBody3D +@export var acceleration: float = 10.0 +@export var crouch_height: float = 0.95 +@export var crouch_speed: float = 3.0 @export var jump_velocity: float = 4.5 @export var mouse_sensitivity_horizontal: float = 0.002 @export var mouse_sensitivity_vertical: float = 0.002 @export var walk_speed: float = 5.0 -@export var run_speed: float = 7.5 +@export var run_speed: float = 8 @onready var camera: Camera3D = $Camera -@onready var ray_cast: RayCast3D = $RayCast3D - +@onready var collision_shape_standing: CollisionShape3D = $CollisionShapeStanding +@onready var collision_shape_crouching: CollisionShape3D = $CollisionShapeCrouching +@onready var ray_cast_look: RayCast3D = $RayCastLook +@onready var ray_cast_crouch: RayCast3D = $RayCastCrouch +var current_speed: float = 0 +var is_crouching: bool = false var is_running: bool = false func _physics_process(delta: float) -> void: + is_crouching = Input.is_action_pressed("crouch") + apply_gravity(delta) handle_jump() handle_running() handle_movement() + handle_crouching(delta) move_and_slide() @@ -32,6 +42,21 @@ func apply_gravity(delta: float) -> void: if is_on_floor(): return velocity += get_gravity() * delta +## It's not generally recommended to modify the shape/size of a collision shape during runtime. +## For this reason, we have 2 collision shapes, with 1 disabled at all times +## along with the changing the height of the camera (using lerp for smoother movement) +func handle_crouching(delta: float) -> void: + if is_crouching: + collision_shape_crouching.disabled = false + collision_shape_standing.disabled = true + camera.transform.origin.y = lerp(camera.transform.origin.y, crouch_height, acceleration * delta) + elif !ray_cast_crouch.is_colliding(): + collision_shape_crouching.disabled = true + collision_shape_standing.disabled = false + camera.transform.origin.y = lerp(camera.transform.origin.y, 1.8, acceleration * delta) + else: + pass # Continue crouching until nothing overhead + func handle_jump() -> void: if not Input.is_action_just_pressed("jump"): return if not is_on_floor(): return @@ -41,20 +66,19 @@ func handle_mouse_look(event: InputEvent) -> void: rotation.y = rotation.y - event.relative.x * mouse_sensitivity_horizontal camera.rotation.x = camera.rotation.x - event.relative.y * mouse_sensitivity_vertical camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-90), deg_to_rad(90)) - ray_cast.rotation.x = camera.rotation.x + ray_cast_look.rotation.x = camera.rotation.x func handle_movement() -> void: var input_dir: Vector2 = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - var speed: float = run_speed if is_running else walk_speed - + set_movement_speed() if direction: - velocity.x = direction.x * speed - velocity.z = direction.z * speed + velocity.x = direction.x * current_speed + velocity.z = direction.z * current_speed else: - velocity.x = move_toward(velocity.x, 0, speed) - velocity.z = move_toward(velocity.z, 0, speed) + velocity.x = move_toward(velocity.x, 0, current_speed) + velocity.z = move_toward(velocity.z, 0, current_speed) ## Determine if should be running. This needs to run prior to handle_movement(). ## Running is disabled when:[br] @@ -67,3 +91,11 @@ func handle_running() -> void: is_running = false if velocity == Vector3.ZERO: is_running = false + +func set_movement_speed() -> void: + if is_crouching: + current_speed = crouch_speed + elif is_running: + current_speed = run_speed + else: + current_speed = walk_speed diff --git a/scenes/player/player.tscn b/scenes/player/player.tscn index dc72afc..0675e8a 100644 --- a/scenes/player/player.tscn +++ b/scenes/player/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=5 format=3 uid="uid://cggiju8k3bkoc"] +[gd_scene load_steps=6 format=3 uid="uid://cggiju8k3bkoc"] [ext_resource type="Script" uid="uid://b6xiwiwwbdapd" path="res://scenes/player/player.gd" id="1_rp718"] [ext_resource type="Script" uid="uid://bruuttf8j7wet" path="res://scenes/player/ray_cast_3d.gd" id="2_dovo2"] @@ -6,24 +6,38 @@ [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dovo2"] height = 1.95 +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_gmlin"] +radius = 0.2 +height = 0.6 + [sub_resource type="CapsuleMesh" id="CapsuleMesh_gmlin"] [node name="Player" type="CharacterBody3D"] script = ExtResource("1_rp718") -[node name="CollisionShape" type="CollisionShape3D" parent="."] +[node name="CollisionShapeStanding" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.953133, 0) shape = SubResource("CapsuleShape3D_dovo2") +[node name="CollisionShapeCrouching" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.536112, 0) +shape = SubResource("CapsuleShape3D_gmlin") +disabled = true + [node name="MeshInstance" type="MeshInstance3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.953133, 0) mesh = SubResource("CapsuleMesh_gmlin") [node name="Camera" type="Camera3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8, -0.005) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8, 0) -[node name="RayCast3D" type="RayCast3D" parent="."] +[node name="RayCastLook" type="RayCast3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8, 0) target_position = Vector3(0, 0, -5) debug_shape_custom_color = Color(1, 0, 0, 1) script = ExtResource("2_dovo2") + +[node name="RayCastCrouch" type="RayCast3D" parent="."] +editor_description = "Y should be just slightly higher than the height of the standing collision shape" +target_position = Vector3(0, 1.96, 0) +debug_shape_custom_color = Color(1, 0, 0, 1)