CharacterBody2D keeps slowly drifting down

Godot Version

4.2.1

Question

I have the following script for my player node:

extends CharacterBody2D

var playerDefaultMovementSpeed: float = 200

func _ready():

	pass # Replace with function body.


func _process(_delta):
	
	var direction: Vector2 = Input.get_vector("left","right","up","down")
	
	velocity = direction * playerDefaultMovementSpeed
	
	move_and_slide()
	
	# Other actions.
	if (Input.is_action_pressed("primaryAction")):
		# Do thing. MYTODO figure out what thing
		$Player/Rock.visible = true
		pass
	else:
		if (Input.is_action_just_released("primaryAction")):
			$Player/Rock.visible = false
			pass # MYTODO what other actions?
	

And i’ve noticed that when I try to run it the player keeps driting down the screen always.

I’ve tried printing the velocity value to ensure it wasn’t always putting a positive y value in the direction but that is not the case (i’ve confirmed that the input map correctly sets the direction value based on the correct left,right,up and down inputs).

I’ve checked that my motion mode was set to Floating but the issue appears in both Floating and Grounded.

I must be missing something else here so any help would be appreciated!

You could share your project, hard to say what it might be. Hints: you should always multiply by delta, because of FPS independence.

Yeah I wanted to share the project originally but it won’t let me upload any tscn files with the upload button so I’m not sure the best way to share it with you.

Regarding the move_and_slide() method I believe it already takes delta into account (When and when NOT to use delta in _process and _physics_process functions - Talk - GameDev.tv)

I’ve decided that the best way to show the Godot project is to get what I have up on Git. I’ll post a link shortly

if your character has a rigidbody2d node, in the inspector, under rigidbody2d section, try setting your gravity scale to 0?

i believe you dont need the underscore in front of delta in the argument for _process()

also, i think you should be handling physics body movement in the _physics_process(delta) callback, not _process(delta), when using characterbody2d.

I’ve replaced _process with _physics_process and didn’t notice any change in my result.

I don’t have a rigidbody2d node since CharacterBody2D is used instead. I do not see a property in the inspector called Gravity. If you set the Motion mode to Grounded there is an Up direction property, but in my case of using Floating it doesn’t apply

In that link you provided it looks like you have to manually adjust for gravity if you want your CharacterBody2D to be affected by it, which seems strange that mine would be affected by this.

1 Like

found this:

extends CharacterBody2D

var speed = 300

func get_input():
	var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	velocity = input_dir * speed

func _physics_process(delta):
	get_input()
	move_and_collide(velocity * delta)

maybe take the float option away too?  dont think its needed.

Judging from the move_and_collide taking input arguments that’s from Godot3. Godot4 won’t run GDScript calls to move_and_collide with an argument provided.

A similar example does appear to be inside of the URL you listed (Using CharacterBody2D/3D — Godot Engine (stable) documentation in English) . Seems like you’ve uncovered a documentation mistake within the Godot manual. I’ll raise a documentation ticket to address that issue.

EDIT my mistake you are calling move_and_collide not move_and_slide like my code has been previously. I’ll give that a shot and see what happens.

code example runs fine in my editor which is 4.2?
edit:sweet! try formmating like the code example above also and see if that solves the issue hopefully!

I replaced my move_and_slide call with move_and_collide

extends CharacterBody2D

var playerDefaultMovementSpeed: float = 200

# Called when the node enters the scene tree for the first time.
func _ready():

	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
	
	var direction: Vector2 = Input.get_vector("left","right","up","down")
	
	velocity = direction * playerDefaultMovementSpeed
	
	move_and_collide(velocity * delta)
	
	# Other actions.
	if (Input.is_action_pressed("primaryAction")):
		# Do thing. MYTODO figure out what thing
		$Player/Rock.visible = true
		pass
	else:
		if (Input.is_action_just_released("primaryAction")):
			$Player/Rock.visible = false
			pass # MYTODO what other actions?
	

And I still notice that my player keeps sliding down.

Just for sanity’s sake, could you maybe try and clone my git project and run it yourself? could be an issue with the installation of Godot on my end? I had this issue with version 4.0 then I upgraded to 4.2.1 so maybe something to do with that somehow???

If you print(direction) and print(velocity), are there any results that are not 0 while not giving input?

doing nothing I get the (0,0) vector while my player slowly drifts down, so I don’t think it’s an input issue?

whatever the rock node is i deleted it and it stopped falling. seems to be the issue. maybe the staticbody2d?

1 Like

Oh that’s a big help. I’ll have a look around there, Thanks!

I see. The rock node has it’s own collision and it was ever so slightly overlapping with the collision of my player, since the rock is above the player it was causing the collision event to push the player down slightly, since the rock is a child of the player it would also get pushed down with it, repeating.

Thanks, that was fun :sweat_smile:

1 Like

cool beans!

also change the scale of rock to 1,1 this also fixed the issue on my end

Be careful to never scale your collision shapes in the editor. The “Scale” property in the Inspector should remain (1, 1) . When changing the size of the collision shape, you should always use the size handles, not the Node2D scale handles. Scaling a shape can result in unexpected collision behavior

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.