I need help understanding why my player is not interacting with any static bodies

Godot Version

4.2 Stable

Question

extends CharacterBody2D

Called every frame. ‘delta’ is the elapsed time since the previous frame.

func _physics_process(delta):
	var speed = 5
	var velocity_x = Vector2(1,0)
	var velocity_y = Vector2(0,1)
	if Input.is_action_pressed("ui_down") or Input.is_key_pressed(KEY_S):
		move_and_collide(velocity_y*speed)
		print("Down")
	if Input.is_action_pressed("ui_up") or Input.is_key_pressed(KEY_W):
		move_and_collide(-velocity_y*speed)
		print("Up")
	if Input.is_action_pressed("ui_left") or Input.is_key_pressed(KEY_A):
		move_and_collide(-velocity_x*speed)
		print("Left")
	if Input.is_action_pressed("ui_right") or Input.is_key_pressed(KEY_D):
		move_and_collide(velocity_x*speed)
		print("Right")

I’ve been at this for a week and I can’t find anyone with my problem that has gotten help that solved the problem. I’m a beginner at this so please help me figure this out.

1 Like

Code looks good, but as the state in the documentation, you should factor in delta to the velocity vector to stay frame-rate independent (despite the physics rate meant to be steady).
Also it might be better to move your player only once, as with your current code, imagine pressing all WASD keys, you will actually move down, then up, then left, then right.

func _physics_process(delta):
	var speed = 5
	var velocity = Vector2.ZERO
	if Input.is_action_pressed("ui_down") or Input.is_key_pressed(KEY_S):
		velocity.y += 1
		print("Down")
	if Input.is_action_pressed("ui_up") or Input.is_key_pressed(KEY_W):
		velocity.y -= 1
		print("Up")
	if Input.is_action_pressed("ui_left") or Input.is_key_pressed(KEY_A):
		velocity.x -= 1
		print("Left")
	if Input.is_action_pressed("ui_right") or Input.is_key_pressed(KEY_D):
		velocity.x += 1
		print("Right")

	velocity = velocity.normalized()
	move_and_collide(velocity*speed*delta)

This way you directly get the final velocity vector. You need to normalize it otherwise you will travel faster in diagonal (both up and left for example, as directions will add up).


Now regarding the collision part, we don’t have enough details to sort this out.
What are you explicitly trying to achieve ?

Other than that, one thing to keep in mind is physic objects appears in a LAYER and detects via a MASK.
Suppose your player appear in layer 1 and other objects in layer 2.
Player will need to scan with mask 2 and objects with mask 1.

But for simplicity sake you might want to have everything on the same layer and mask.

You can test for collisions as move_and_collide() returns the result of the collision.

func _physics_process(delta):
	# ...
	var result_kinematic_collision_2d = move_and_collide(velocity*speed*delta)
	if result_kinematic_collision_2d != null:
		print("Collision detected!")

What do you mean by not interacting? Do you mean not colliding?

Did you add collision shapes to both objects?

In almost every case when it comes to collisions, the issue is with collision shapes not being on the same layer mask. If reading that sentence made you go “wdym mate” then I recommend a start-to-finish tutorial to get a grasp of main engine concepts - I found that very helpful when starting myself. This is the best such tutorial I’ve seen so far: https://www.youtube.com/watch?v=nAh_Kx5Zh5Q

That tutorial will not only go over collisions, but also show you how to do movement with just 3 lines of code:

# up, down, etc are tied to keys (up arrow, w) and (down arrow, s) respectively  by you in Project Settings -> Input Map
var direction = Input.get_vector("left", "right", "up", "down") 
self.velocity = direction * speed
move_and_slide()

You don’t need to use move_and_collide() for a CharacterBody2D to collide with / be affected by static and rigid bodies. As long as CharacterBody2D’s collision shape reacts to mask layer that static/rigid objects are on, the interactions are automatic. I.e. walking on floor / getting stopped by walls are both automatic.

You only want to use move_and_collide() when you want to override that behavior and handle things manually. It’s very unlikely to be something beginners would want, though, so I’d advise against using move_and_collide() until you have a better handle on the engine.

1 Like