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”?
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)
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
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