My player just flies up endlessly after spawning, and I don't know why> Please help

Godot Version

Godot 4.4.1

Question

After iI spawn my player from the character select, the player just flies up endlessly into the air. I added debug to check _is_on_ground and velocity. _is_on_ground is always true and velocity is 0 but the player still flies into the air.

extends CharacterBody3D

enum player_states { MOVE, JUMP, INTERACT, FALLING }
var current_state = player_states.MOVE

@export var speed := 6.0
@export var sprint_speed := 10.0
@export var gravity := 10.0
@export var jump_force := 10.0

Camera & model placeholders

@onready var camera_gimbal := $Cam_Gimbel
@onready var camera := $Cam_Gimbel/Camera3D
@onready var model_holder := $CharacterModel # Empty Node3D

Animation system (assigned after loading model)

var anim_player: AnimationPlayer
var anim_tree: AnimationTree
var anim_state: AnimationNodeStateMachinePlayback
var player_body: Node3D

Movement data

var angular_speed := 10
var direction := Vector3.ZERO
var movement := Vector2.ZERO

func _ready():
# Load selected model (set from character select)
var model_scene = load(Global.selected_model_path)
var model = model_scene.instantiate()

model_holder.add_child(model)
model.transform = Transform3D.IDENTITY

# Try to assign animation systems from model
anim_player = model.get_node_or_null("Anim_Player")
anim_tree = model.get_node_or_null("Anim_Tree")
player_body = model.get_node_or_null("Rig")

if anim_tree:
	anim_tree.active = true
	anim_state = anim_tree.get("parameters/playback")
	anim_state.travel("Ground_state")
elif anim_player:
	anim_player.play("Idle")
else:
	push_warning("No AnimationTree or AnimationPlayer found on model")

# Ensure initial velocity is zero
velocity = Vector3.ZERO

func _physics_process(delta):
# Apply gravity always when not on floor
if not is_on_floor():
velocity.y -= gravity * delta
else:
velocity.y = 0

# Handle state transitions and movement
match current_state:
	player_states.MOVE:
		move(delta)
		if not is_on_floor():
			current_state = player_states.FALLING
		elif Input.is_action_just_pressed("ui_select"):
			current_state = player_states.JUMP
	player_states.JUMP:
		jump(delta)
	player_states.INTERACT:
		interact(delta)
	player_states.FALLING:
		falling(delta)

move_and_slide()

# Debug output to track issues
print("State: ", player_states.keys()[current_state], " | is_on_floor: ", is_on_floor(), " | velocity.y: ", velocity.y)

func _input(event):
if Input.is_action_just_pressed(“ui_accept”):
current_state = player_states.INTERACT
# Note: Jump is handled in _physics_process to avoid input conflicts

func input_movement(delta):
movement = Input.get_vector(“ui_left”, “ui_right”, “ui_up”, “ui_down”)
direction = Vector3(movement.x, 0, movement.y).rotated(Vector3.UP, camera.rotation.y).normalized()

if direction != Vector3.ZERO:
	var sprint = Input.is_action_pressed("ui_sprint")
	var current_speed = sprint_speed if sprint else speed
	velocity.x = direction.x * current_speed
	velocity.z = direction.z * current_speed
	player_body.rotation.y = lerp_angle(player_body.rotation.y, atan2(velocity.x, velocity.z), delta * angular_speed)
else:
	velocity.x = move_toward(velocity.x, 0, speed)
	velocity.z = move_toward(velocity.z, 0, speed)

func move(delta):
input_movement(delta)

var sprint = Input.is_action_pressed("ui_sprint")
if direction != Vector3.ZERO:
	anim_tree.set("parameters/Ground_state/conditions/Walking", not sprint)
	anim_tree.set("parameters/Ground_state/conditions/Running", sprint)
	if sprint:
		anim_state.travel("Ground_state/Run")
	else:
		anim_state.travel("Ground_state/Walk")
else:
	anim_tree.set("parameters/Ground_state/conditions/Standing", true)
	anim_state.travel("Ground_state/Idle")

func jump(delta):
if is_on_floor(): # Only allow jump if on floor
velocity.y = jump_force
anim_tree.set(“parameters/conditions/Jumping”, true)
anim_state.travel(“Air_state”)

# Transition to FALLING if moving downward or not on floor
if not is_on_floor() and velocity.y <= 0:
	current_state = player_states.FALLING

func falling(delta):
input_movement(delta) # Allow movement while falling
if is_on_floor():
anim_tree.set(“parameters/conditions/On_ground”, true)
anim_state.travel(“Landing”)
current_state = player_states.MOVE
else:
anim_tree.set(“parameters/conditions/On_ground”, false)

func interact(delta):
input_movement(delta)
anim_state.travel(“Interact_state/Interact”)
await get_tree().create_timer(2.0).timeout
current_state = player_states.MOVE
anim_tree.set(“parameters/Ground_state/conditions/Walking”, false)
anim_tree.set(“parameters/Ground_state/conditions/Running”, false)
anim_tree.set(“parameters/conditions/On_ground”, is_on_floor())
anim_tree.set(“parameters/conditions/Jumping”, false)

velocity.y -= gravity * delta

Pretty sure this is your issue, make it += as negative y values go up.

Thank you I got it sorted was a collider issue