help me figure out why I can't move in 3d:

extends CharacterBody3D

enum State { IDLE, RUN, JUMP, ATTACK }
var state = State.IDLE

var velocity = Vector3.ZERO  # Adding velocity as a member variable

@export var movement_data : MovementData
@export var stats : Stats

# References
@onready var animation_tree : AnimationTree = $AnimationTree
@onready var animation_state : AnimationNodeStateMachinePlayback = animation_tree.get("parameters/playback")

func _ready():
	animation_tree.active = true
	stats.health = stats.max_health

func _physics_process(delta):
	process_movement_input(delta)
	process_gravity(delta)
	process_actions()

	# Move and slide with snap when on floor, else without snap
	var snap = Vector3.DOWN * 20 if is_on_floor() else Vector3.ZERO
	move_and_slide_with_snap(velocity, snap, Vector3.UP)
	update_animation_state()

func process_gravity(delta):
	if not is_on_floor():
		velocity.y += movement_data.gravity * movement_data.gravity_scale * delta
	else:
		velocity.y = -0.01  # The small sinking force to keep the player snapped to the floor

func process_movement_input(delta):
	print("Input Vector: ", input_vector)
	print("Direction: ", direction)
	print("Velocity before: ", velocity)
	var input_vector = Vector2(Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
							   Input.get_action_strength("move_back") - Input.get_action_strength("move_forward"))

	if input_vector.length() > 0:
		input_vector = input_vector.normalized()  # Normalize input_vector if it has a length
		var direction = -transform.basis.z * input_vector.y + transform.basis.x * input_vector.x


		state = State.RUN
		velocity.x = direction.x * movement_data.max_speed
		velocity.z = direction.z * movement_data.max_speed

		look_at(global_transform.origin + direction, Vector3.UP)  # Rotate player to face the direction of movement
	else:
		if state == State.RUN:
			state = State.IDLE  # When there’s no input, and we were running, switch to idle state
		velocity.x = lerp(velocity.x, 0, movement_data.friction * delta)
		velocity.z = lerp(velocity.z, 0, movement_data.friction * delta)

func process_actions():
	if Input.is_action_just_pressed("jump") and is_on_floor():
		perform_jump()

	if Input.is_action_just_pressed("attack"):
		perform_attack()

func perform_jump():
	velocity.y = movement_data.jump_strength
	state = State.JUMP  # Update state to JUMP when jumping is performed
	# Handle jump animation, sound etc.

func perform_attack():
	state = State.ATTACK  # Set state to ATTACK
	animation_state.travel("Attack")
	# Add attack logic here …

func update_animation_state():
	match state:
		State.IDLE:
			animation_state.travel("Idle")
		State.RUN:
			animation_state.travel("Run")
		State.JUMP:
			if velocity.y > 0:
				animation_state.travel("Jump")
			else:
				animation_state.travel("Fall")
		State.ATTACK:
			# Assuming perform_attack will ensure the state transitions out of ATTACK when done

# Override method from player base to handle damage and death
func take_damage(damage: int):
	stats.health -= damage
	if stats.health <= 0:
		die()
	else:
		# Play damage animation, sound etc.

func die():
	state = State.IDLE  # Consider whether you want to change animation or state after death
	# Play death animation, particle effect etc.
	queue_free()  # Be sure you want to remove the player from the scene at this point