how to make a first person state machine? 3.5.1

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

how would i make a state machine for a fps controller, i want something so it detects when im walking/crouching/running/idle so it plays an animation.

main code for player (if need player tscn’s and all the scripts let me know) :

extends KinematicBody

var mouse_sensitivity = 1
var joystick_deadzone = 0.2

var run_speed = 20
var walk_speed = run_speed / 2
var crouch_speed = run_speed / 6
var jump_height = 4.5

var current_speed = run_speed

var ground_acceleration = 10
var air_acceleration = 5
var acceleration = air_acceleration

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

var gravity = 14
var gravity_vec = Vector3()

var snapped = false
var can_jump = true
var crouched = false
var can_crouch = true

var player_speed = 0
var falling_velocity = 0

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

	

func _input(event):

if event is InputEventMouseMotion:
	rotation_degrees.y -= event.relative.x * mouse_sensitivity / 18
	$Head.rotation_degrees.x -= event.relative.y * mouse_sensitivity / 18
	$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x, -90, 90)
	
direction = Vector3()

func _physics_process(delta):

if Input.get_joy_axis(0, 2) < -joystick_deadzone or Input.get_joy_axis(0, 2) > joystick_deadzone:
	rotation_degrees.y -= Input.get_joy_axis(0, 2) * 2
if Input.get_joy_axis(0, 3) < -joystick_deadzone or Input.get_joy_axis(0, 3) > joystick_deadzone:
	$Head.rotation_degrees.x = clamp($Head.rotation_degrees.x - Input.get_joy_axis(0, 3) * 2, -90, 90)


direction = Vector3()

if Input.is_key_pressed(KEY_W) or Input.is_key_pressed(KEY_Z) or Input.is_key_pressed(KEY_UP):
	direction.z += -1
if Input.is_key_pressed(KEY_S) or Input.is_key_pressed(KEY_DOWN):
	direction.z += 1
if Input.is_key_pressed(KEY_A) or Input.is_key_pressed(KEY_Q) or Input.is_key_pressed(KEY_LEFT):
	direction.x += -1
if Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT):
	direction.x += 1

direction = direction.normalized()


	

if direction == Vector3():
	direction.z = Input.get_joy_axis(0, 1)
	direction.x = Input.get_joy_axis(0, 0)
	
	
	if direction.z < joystick_deadzone and direction.z > -joystick_deadzone:
		direction.z = 0
	if direction.x < joystick_deadzone and direction.x > -joystick_deadzone:
		direction.x = 0


direction = direction.rotated(Vector3.UP, rotation.y)



if is_on_floor():
	if snapped == false:
		falling_velocity = gravity_vec.y
		land_animation()
	acceleration = ground_acceleration
	movement.y = 0
	gravity_vec = -get_floor_normal() * 10
	snapped = true
else:
	acceleration = air_acceleration
	if snapped:
		gravity_vec = Vector3()
		snapped = false
	else:
		gravity_vec += Vector3.DOWN * gravity * delta

if is_on_floor():
	if Input.is_key_pressed(KEY_SHIFT) or Input.get_joy_axis(0, 6) >= 0.6:
		current_speed = run_speed
	else:
		current_speed = walk_speed
	if crouched:
		current_speed = crouch_speed

if Input.is_key_pressed(KEY_SPACE) or Input.is_joy_button_pressed(0, JOY_XBOX_A):
	if is_on_floor() and can_jump:
		snapped = false
		can_jump = false
		gravity_vec = Vector3.UP * jump_height
else:
	can_jump = true

if is_on_ceiling():
	gravity_vec.y = 0

if Input.is_key_pressed(KEY_CONTROL) or Input.is_key_pressed(KEY_C) or Input.is_joy_button_pressed(0, JOY_XBOX_B):
	crouch_animation(true)
else:
	crouch_animation(false)
	
	

velocity = velocity.linear_interpolate(direction * current_speed, acceleration * delta)

movement.x = velocity.x + gravity_vec.x
movement.z = velocity.z + gravity_vec.z
movement.y = gravity_vec.y

movement = move_and_slide(movement, Vector3.UP)

player_speed = movement.length()
if Input.is_action_just_released("crouch") and is_on_ceiling():
	crouch_animation(false)
	

func land_animation():
var movement_y = clamp(falling_velocity, -20, 0) / 40

$LandTween.interpolate_property($Head/Camera, "translation:y", 0, movement_y, 0.1, Tween.TRANS_SINE, Tween.EASE_OUT)
$LandTween.interpolate_property($Head/Camera, "translation:y", movement_y, 0, 0.25, Tween.TRANS_SINE, Tween.EASE_IN_OUT, 0.1)
$LandTween.start()

func crouch_animation(button_pressed):
if button_pressed:
if not crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.25, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.25, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.35, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = true
else:
if crouched:
$CrouchTween.interpolate_property($MeshInstance, “mesh:mid_height”, $MeshInstance.mesh.mid_height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($CollisionShape, “shape:height”, $CollisionShape.shape.height, 0.75, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.interpolate_property($Head, “translation:y”, $Head.translation.y, 1.6, 0.2, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
$CrouchTween.start()
crouched = false

if anyone wants to add me on discord to explain further, Dy#3001

Dylised | 2022-11-16 03:40

You should probably check YouTube videos on state machines as this is quite and advanced topic and would need some time to cover in details.

magicalogic | 2022-11-17 04:26