Weird Glitch with player character, cannot move in 1 scene

Godot Version

4.2.2

Question

My character works and I can move around fully in the first 3D scene I made when creating the game, (it is a player prefab that is placed in the scene) and when I create a second 3D scene with the player prefab placed inside I cannot move at all? The footstep sounds of the player still work, showing that Godot thinks my player is moving, but it is not. I can still look around which also shows the player script is running, I just cannot move with WASD. Feel free to ask questions and I’ll do my best to answer them.

Here is my code for my player character:
extends CharacterBody3D

signal footstep_ready_signal
var SPEED = 1.25
const JUMP_VELOCITY = 4.5

#Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting(“physics/3d/default_gravity”)
@onready var neck := $Neck
@onready var camera := $Neck/Camera3D
@onready var footstep := $footsteps
@onready var lighter = $Neck/Camera3D/OmniLight3D
@onready var lighter_walking_anim = $Neck/Camera3D/lighter/walking_anim
@onready var flicker_anim = $Neck/Camera3D/lighter/fire_anim
var footstep_ready = true
var footstep_sound
var moving = false
var anim_playing = false
var lighter_on = true

func _unhandled_input(event):
# if mouse clicks window then it gets locked
if event is InputEventMouseButton:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

# if player clicks escape then mouse is unlocked
elif event.is_action_pressed("ui_cancel"):
	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

# player mouse camera movement
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
	if event is InputEventMouseMotion:
		neck.rotate_y(-event.relative.x * 0.008)
		camera.rotate_x(-event.relative.y * 0.008)
		camera.rotation.x = clamp(camera.rotation.x, -1.3, 1.3)

func _physics_process(delta):

# flame flicker animation
flicker_anim.play("flame_flicker")

if velocity != Vector3(0, 0, 0):
	moving = true
else:
	moving = false

# Add the gravity.
if not is_on_floor():
	velocity.y -= gravity * delta


# Get the input direction and handle the movement/deceleration.
var input_dir = Input.get_vector("left", "right", "forward", "backward")
var direction = (neck.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction and is_on_floor():
	print(direction)
	velocity.x = direction.x * SPEED
	velocity.z = direction.z * SPEED
	
	lighter_walking_anim.play("walking")
	anim_playing = true

elif is_on_floor():
	velocity.x = move_toward(velocity.x, 0, SPEED)
	velocity.z = move_toward(velocity.z, 0, SPEED)
	if anim_playing == true:
		lighter_walking_anim.pause()

move_and_slide()

# flashlight functionality usiung 'F' key
if Input.is_action_just_pressed("flashlight"):
	if lighter.light_energy > 0.08 and lighter.light_energy < 0.12:
		lighter.light_energy = 0
		lighter_on = false
	elif lighter.light_energy == 0:
		lighter.light_energy = 0.1
		lighter_on = true
	
	# plays flashlight sound
	$flashlight_click.play()
	
# sprint functionality
if Input.is_action_pressed("sprint"):
	SPEED = 3.0
	$footstep_timer.wait_time = 0.38
	lighter_walking_anim.speed_scale = 3
else:
	SPEED = 1.25
	$footstep_timer.wait_time = 0.6
	lighter_walking_anim.speed_scale = 1.8

if Input.is_action_just_pressed("sprint"):
	if moving == true:
		footstep.play()
	
# footstep detector if is walking
if Input.is_action_pressed("forward") or Input.is_action_pressed("left") or Input.is_action_pressed("right") or Input.is_action_pressed("backward"):
	_play_footstep()

func _play_footstep():
if footstep_ready == true and moving == true:
footstep_ready = false
footstep.play()
$footstep_timer.start()

func _on_footstep_timer_timeout():
footstep_ready = true

func _on_flicker_timer_timeout():
if lighter_on == true:
lighter.light_energy = randf_range(0.08, 0.12)
$flicker_timer.start()

Here is a screenshot of the new scene where the player doesn’t work:
image

The ! on the player is just from the size, even with the ! it works on the original scene.

I think code and or a screenshot of this scene would be helpful here

I have edited the post to include some more info, but because I am a new poster it only allows me to add 1 embedded image.

For clarification:

  • Can you actually see the player? If not, maybe it’s a z-index issue where they’re drawn under the level?
  • If this is a different level, maybe the player is trapped in a wall due to collision masks on other objects in this scene not being set right?

It is a first person 3D game, so I do not know if I can see the player when playing it. I can see it in the editor window, if that’s what you mean. It is not invisible.
I do not having any walls in the game, only a floor to test the player, and also the player falls down if I place it above the floor but I cannot move it when it is falling nor when it hits the ground.

Maybe its something with the collision? Whats inside the floor-node?

the floor and the wall prefabs are the same, both of them only have a root rigidbody node, a collision shape 3D child and a mesh instance 3D child. I’m pretty sure this is what it is, but I’ll have to check to make sure.

I suggest to not use "Node"s in between Node3D’s since Nodes dont have a position and that can mess up the child positions in relation to the parent node3d

1 Like

If you meant the Rigidbody, it is a Rigidbody3D I just forgot to mention it. I tested the floor after it had been unparented from the ‘Node’ and it still did not work.

Does the floor move? if not it should be a StaticBody3D. Also looks like the player in the scene tree has a warning, what is that warning?

Thats the warning

The floor does not move, because I have the same prefab used as a wall in the first scene (that works)

I was wrong about the floor and wall scenes, they are a mesh instance 3D with a static body 3D child, and a collision shape 3D as a child of the static body.

just made a 3rd level to test, it doesn’t work in that one either. only in the first level I made.

In your code you test if you are moving, before you even calculate the velocity. Put the

if velocity != Vector3(0, 0, 0):
    moving = true
else:
    moving = false

after you calculate the velocity

even after doing this the footsteps still play, showing godot still thinks my player is moving

The only logical explanation that i can think of is, that your player is blocked in your other scenes and wont move because of that

there is literally nothing blocking the player. if I spawn the player far above the floor I still cannot move in the air. I’m hoping this is not a bug in Godot 4.2.2 and is something fixable

can you print the velocity before move_and_slide() to check if it is > 0


Added a print statement that prints the velocity 1 line above the move_and_slide. godot fully thinks my player is moving but the move_and_slide isn’t working?