how do i add crouching to my 3d game?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dylised

here is my code:

extends KinematicBody

var speed = 3.5
const ACCEL_DEFAULT = 7
const ACCEL_AIR = 1
onready var accel = ACCEL_DEFAULT
var gravity = 9.8
var jump = 3

var cam_accel = 40
var mouse_sense = 0.1
var snap

var direction = Vector3()
var velocity = Vector3()
var gravity_vec = Vector3()
var movement = Vector3()

onready var head = $Head
onready var camera = $Head/Camera

func _ready():
#hides the cursor
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _input(event):
#get mouse input for camera rotation
if event is InputEventMouseMotion:
rotate_y(deg2rad(-event.relative.x * mouse_sense))
head.rotate_x(deg2rad(-event.relative.y * mouse_sense))
head.rotation.x = clamp(head.rotation.x, deg2rad(-89), deg2rad(89))

func _process(delta):
#camera physics interpolation to reduce physics jitter on high refresh-rate monitors
if Engine.get_frames_per_second() > Engine.iterations_per_second:
camera.set_as_toplevel(true)
camera.global_transform.origin = camera.global_transform.origin.linear_interpolate(head.global_transform.origin, cam_accel * delta)
camera.rotation.y = rotation.y
camera.rotation.x = head.rotation.x
else:
camera.set_as_toplevel(false)
camera.global_transform = head.global_transform

func _physics_process(delta):
#get keyboard input
direction = Vector3.ZERO
var h_rot = global_transform.basis.get_euler().y
var f_input = Input.get_action_strength(“move_backward”) - Input.get_action_strength(“move_forward”)
var h_input = Input.get_action_strength(“move_right”) - Input.get_action_strength(“move_left”)
direction = Vector3(h_input, 0, f_input).rotated(Vector3.UP, h_rot).normalized()

#jumping and gravity
if is_on_floor():
	snap = -get_floor_normal()
	accel = ACCEL_DEFAULT
	gravity_vec = Vector3.ZERO
else:
	snap = Vector3.DOWN
	accel = ACCEL_AIR
	gravity_vec += Vector3.DOWN * gravity * delta
	
if Input.is_action_just_pressed("jump") and is_on_floor():
	snap = Vector3.ZERO
	gravity_vec = Vector3.UP * jump

#make it move
velocity = velocity.linear_interpolate(direction * speed, accel * delta)
movement = velocity + gravity_vec

move_and_slide_with_snap(movement, snap, Vector3.UP)
:bust_in_silhouette: Reply From: GDnoob

you can shrink the collision shape to do a very basic crouching

func _crouch():
    #Use a tween to make it smoother
    var t := create_tween()
    #Tween y axis of the collision shape to 0.5 in 0.1 second
    t.tween_property($CollisionShape,size:y,0.5,0.1)
func _stand():
    var t := create_tween()
    t.tween_property($CollisionShape,size:y,1,0.1)
:bust_in_silhouette: Reply From: stormreaver

I would handle this via the AnimationPlayer. I attach a bone node (I can’t think of the node name off hand, and I don’t have Godot handy where I’m at) to my rigged characters, and make the camera a child of that bone node. This makes the camera automatically move with its parent bone node.

One of the animations my characters have is a crouch, so the camera automatically moves into the crouch position when the crouch animation is played. It’s the same thing with jumps. This makes it unnecessary to write any code to handle most first-person views. Other view-based actions (such as glancing around without turning) are a simple matter of reparenting the camera as necessary.

This method eliminates a lot of coding.