CollisionShape2D connecting with other CollisionShape2D

Godot Version

godot-4.1.2

Question

I am noticing when I walk up to an enemy that it seems like the _physics_process is speeding up causing my player and the enemy to race across the map. Additionally it seems like their collision shapes are connecting and moving one another. Appreciate any help to understand this problem, I’ve tried searching google, the youtube video I was following, and the forums but I can’t seem to find the right keywords to find anyone else having the same issue.

player

func _physics_process(_delta):
	var input_direction = Vector2(
		Input.get_action_strength("right") - Input.get_action_strength("left"),
		Input.get_action_strength("down") - Input.get_action_strength("up")
	)
	
	update_animation_parameters(input_direction)
	
	velocity = input_direction.normalized() * move_speed
	
	move_and_slide()
	
	pick_new_state()

func update_animation_parameters(move_input : Vector2):
	if(move_input != Vector2.ZERO):
		animation_tree.set('parameters/Walk/blend_position', move_input)
		animation_tree.set('parameters/Idle/blend_position', move_input)

func pick_new_state():
	if(velocity != Vector2.ZERO):
		state_machine.travel("Walk")
	else:
		state_machine.travel("Idle")

enemy

func _physics_process(delta):
	velocity = move_direction.normalized()  * move_speed
	
	move_and_slide()

func select_new_direction():
	move_direction = Vector2(
		randi_range(-1, 1),
		randi_range(-1, 1)
	)
	
	print_debug(move_direction)

	
func pick_new_state():
	if(current_state == MONSTER_STATE.IDLE):
		state_machine.travel("Walk")
		current_state = MONSTER_STATE.WALK
		select_new_direction()
		timer.start(walk_time)
	elif(current_state == MONSTER_STATE.WALK):
		state_machine.travel("Idle")
		current_state = MONSTER_STATE.IDLE
		timer.start(idle_time)


func _on_timer_timeout():
	pick_new_state()

Link to video showing issue.

This is (unfortunately? not sure) the current behavior of the engine where two bodies will stick to each other because the engine doesn’t know what to do when collision occurs (and doesn’t let you configure it).

You can:
a) use Area2D for root class of enemies, then decide in _on_area_entered how you want enemy and/or player to handle collision - do you push the enemy back, just let enemy stay on top of player, etc.

b) use var collision_info = move_and_collide() instead and then inspect collision_info object and based on what object player and/or enemy collides with also decide if you want to knock back, ignore collision, etc. This WILL throw away all benefits of using move_and_slide though. I haven’t used it myself coz it seems like an overkill for my simple case of bullet hell/roguelike.

c) maybe? make enemy a RigidBody2D, disable gravity on it, and screw around with its bounce property? not sure

d) use a different physics engine like Rapier. I also haven’t (yet) done that and am not sure if it fixes this specific problem, but I hear 3rd party physics servers/engines are better all-around. I will most definitely switch to one of them once I focus on optimizing performance.

Maybe someone else has simpler solutions :man_shrugging: I’m still a newb with Godot.

I really appreciate your comment.

I actually implemented a rigid2d for another component and left the game running for a while and the enemy ran into it long enough to give it movement. I was very confused by this for a while. So I might just need to implement some kind of bounce back on area2d. I’m not sure how other devs handle this when walking into NPCs who don’t inflict damage unless its a smaller bounce back to break the collision. I will experiment with your suggestions and report back if I find a suitable solution.

Yep, it’s a smaller bounce or teleporting enemy away a pixel :smiling_face_with_tear: Both accomplish the same thing.

Basically move_and_slide() is (I’m guessing) really designed to move along floors/inclines without jitter. Great, but I’m not sure how to disable this for non-StaticBody2D interactions.

Honestly, though, it’s basically never the case that you want a player to slide against an enemy anyway - you want them to take dmg, and one of them to be pushed away, or smth. So the engine is forcing you to code that, which is like… needed anyway? So ehh.

I guess my concern later down the line was for friendly NPC collision. Normally you would push against them without that sort of interaction.