Rigidbody2D body enter detected only one side?

Godot Version

v4.7.1.stable.official [a13da4feb] using Default 2D Physics

Question

I have a Player which extends CharacterBody2D. When it enters in collision with an Enemy which extends RigidBody2D, I want the player to be pushed to the opposite direction. So I made my enemy like this, with a circle CollisionShape2D. It also have two RayCast2D to apply movement direction changes.

func _on_body_entered(body: Node) -> void:
	if body is Player:
		var direction : Vector2 = body.global_position - global_position
		body.push_body(direction.normalized() * 500)
		body.take_damages(1)

When the player goes to the enemy by its back, the body_entered() signal is only sent from its back.

This is the enemy movement script. I use the linear_velocity to move it. And move_and_slide() for player. Both inside the _physics_process()

extends Node

@export var direction : bool = true
@export var speed : float = 2

@onready var left_raycast : RayCast2D = $LeftRaycast
@onready var right_raycast : RayCast2D = $RightRaycast

var parent : RigidBody2D

func _ready() -> void:
	parent = get_parent() as RigidBody2D

func _physics_process(_delta: float) -> void:
	var dir_vector : Vector2
	if direction:
		dir_vector = parent.global_transform.basis_xform(Vector2.LEFT)
	else:
		dir_vector = parent.global_transform.basis_xform(Vector2.RIGHT)
	parent.linear_velocity = speed * dir_vector
	
	if direction and left_raycast.is_colliding(): 
		direction = false
	if !direction and right_raycast.is_colliding():
		direction = true

What did I do wrong? Is my node architecture or the way I implemented the feature “good”?

What do you mean with?

Do you want to apply knocback?

The knockback is already coded and applied… only when the enemy moves toward the player (like the video joined in the first post).

I want to understand why the knockback is applied that way and not also when the player is just standing upon it? It’s hard to describe (that’s why I uploaded a video though)

:face_with_raised_eyebrow:

Absolutely not. I encountered a weird behaviour with a simple collision system. I don’t understand what is wrong with my question nor my problem?

Maybe my formulation in english isn’t clear enough because that is not my native language at all, and excuse me for that. But insulting me of “vibe coder” from a legit question is too much.

If you need more details or a GIF, somewhat useful to help community understand what is exactly my problem, just tell me instead of bashing me


Try to place you rays on top of you character.

Sorry but the problem was so simple dat i thougt it came from AI.
and i have no idea why direction is an bool instead of an int.

Hm… I dont know.

I’d move the hit detection off the rigid body. Either check on the player side with get_slide_collision after move_and_slide, since the player always knows what it hit, or give the enemy an Area2D slightly larger than its CollisionShape2D and use its body_entered for the knockback and damage. The Area2D is better for this and fires no matter who walked into who. And since you’re setting linear_velocity directly every frame, you’re overriding the physics simulation anyway, so a CharacterBody2D enemy with the same raycast flip logic would give you this movement with fewer surprises, then the Area2D handles the hits.

Ok thank you very much! I don’t understand why the RigidBody2D<->PhysicsBody2D detection is not triggered properly on moving objects. Maybe the way the physics server runs?

But using an additional Area2D is working. I made one that I attached as a child of my Enemy