My 3dcharacterbody is sliding without ANY input

4.4

So for some, UNKNOWN REASON, my character keeps on moving without input and I can’t jump. I have no idea if it’s a problem with my script or if it’s with the scene, but I need help DESPERATELY. Also NO removing .normalized() does not do anything

extends CharacterBody3D

@onready var pivot: Node3D = $pivot

var  SPEED = 5.0
const JUMP_VELOCITY = 4.5
var mouse_sensitivtiy = 0.5


func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED



func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("LEFT", "rIGH", "uuuuuuppp", "Dowwnnn")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)
	move_and_slide()
# camera movement.
func _input(event):
	if event is InputEventMouseMotion:
		rotate_y(deg_to_rad(-event.relative.x * mouse_sensitivtiy))
		pivot.rotate_x(deg_to_rad(-event.relative.y * mouse_sensitivtiy))
		pivot.rotation.x = clamp(pivot.rotation.x,deg_to_rad(-90),deg_to_rad(45))
````Preformatted text`

can you show the scenetree of the character?

Why are you using the walrus operator (:=)?

The first thing I’d suggest is disabling everything from var input_dir = ... down to the line before move_and_slide() and seeing if you still have the problem.

1 Like

I can’t since I’m a new user

the only reason you shouldnt be able to jump is, that your body is not on the floor. You can show collision_shapes when you run the game, by clicking on “debug” → “show collisionshapes”.

Switch these lines of code:
var SPEED = 5.0

velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)

to this:

velocity.x = lerp(velocity.x, 0.0, SPEED)
velocity.z = lerp(velocity.z, 0.0, SPEED)

If you start your scene and the player is standing still, and after first input it doesn’t stop moving the first issue might be is that the velocity is a float variable, and the second argument in the move_toward() method is just 0, which is an integer, also for most gradual value changes I just use the lerp() method.

That’s not how lerp() is meant to be used. That gives you nonlinear, framerate dependent changes.

1 Like

You need to make sure that the velocity is being increased on one axis when applying gravity

velocity.y

Okay maybe it’s not suited for op, but what’s negative about it being non-linear? or how is it supposed to be used?

“lerp” is short for Linear Interpolation, so…

The way lerp() is intended to be used is with fixed source arguments and a varying time argument; when you do that, lerp() produces consistent results regardless of the frame rate:

var old_x: float
var new_x: float
var time:  float

func _start_lerp(ox: float, nx: float) -> void:
    old_x = ox
    new_x = nx
    time  = 0.0

func _do_lerp(delta: float) -> float:
    time += delta
    if time >= 1.0: return new_x
    return lerp(old_x, new_x, time)

With that kind of use of lerp(), you’ll get linear results regardless of the frame rate; even at 2fps or 240fps, it will animate the interpolation linearly over the given time. This is usually what you want; you don’t usually want the animation to change depending on the frame rate.

What I see around here a lot is people doing x = lerp(x, target, 0.5) or the like, and that produces exponential interpolation that depends entirely on the frame rate. Each time it’s called, that particular example is going to move x half the distance between its current value and the target value, which means:

  • it’s an exponential curve; x moves half as far every update and won’t actually reach the target until roundoff error kicks in
  • because it’s modifying the input value, a game running at 30hz will change speed half as fast as a game running at 60hz
  • worse, if your frame rate isn’t consistent, neither is your interpolation
1 Like