Area2D hitbox and hurtbox collision often does not work as intended

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By amaou310

As you can see from the gif, player hurtbox collision often does not work as intended and I have no idea why. I would appreciate if you could help me to solve this problem. I am guessing this problem is due to the object moving too fast.

Both hitbox and hurtbox are the area2d and collisionshape2d.

Player script:

class_name Player

extends KinematicBody2D

var speed = 200
var jump_strength = 570
var air_jump_strength := 550
var air_jump = true
var _jumps_made := 0
var gravity = 1500
var acceleration = 60
var friction = 20
var air_friction = 10
var dir := 1
var knockbackdir := 1
var knockback := -150

var _velocity := Vector2.ZERO

onready var position2D = $Position2D
onready var _animation_player: AnimationPlayer = $Position2D/PlayerSkinIK/AnimationPlayer

func get_input_direction() -> float:
	var _horizontal_direction = (
		- Input.get_action_strength("move_left")
	return _horizontal_direction

func _process(delta: float) -> void:
	if get_global_mouse_position().x > $Position2D/PlayerSkinIK.global_position.x:
		dir == -1
		knockbackdir == -1
		dir == 1
		knockbackdir == 1

func _on_HurtboxPlayer_area_entered(area: Area2D):
	if == "HitboxMushroom01":
		knockbackdir == -1
		_velocity.y += -600
		_velocity.x = knockbackdir * knockback

Move State Script:

extends PlayerState

export (NodePath) var _animation_player
onready var animation_player: AnimationPlayer = get_node(_animation_player)

func enter(_msg := {}) -> void:

func physics_update(delta: float) -> void:
	if not player.is_on_floor(): #If player is not on floor, FALL STATE
	if not is_zero_approx(player.get_input_direction()): #If Player is moving, calculate Player's velocity.x 
		player._velocity.x = player.get_input_direction() * player.speed
	player._velocity.y += player.gravity * delta #Gravity Calculation
	player._velocity = player.move_and_slide(player._velocity, Vector2.UP)
	if Input.is_action_just_pressed("jump"): #If input jump pressed, JUMP STATE
		if Input.is_action_pressed("ui_down"):
	elif is_zero_approx(player.get_input_direction()): #If Player is Not Moving, IDLE STATE

I have trouble seeing what is going wrong, since you haven’t explained what you are trying to accomplish. It will be hard to help you with your problem if we don’t know what you intend to do and what is going wrong

godot_dev_ | 2022-08-03 15:07

My apologies for not being clear. I want my player to be bounced off from an enemy every time when hurtbox entered hitbox. However, player’s hurtbox often ignores collision or bounce upward instead. Do you have any idea why this problem cause.

amaou310 | 2022-08-04 01:54

:bust_in_silhouette: Reply From: Inces

I bet your knockback code collides with your movement code. Show the movement code.

Thank you Inces. Please do check added movement script.

amaou310 | 2022-08-04 02:10

Yes, this is what I suspected.

When player is moving, You arbitrary set its velocity.x to the value calculated from input only.
But when collision occurs, You arbitrary set velocity.x to another value, calculated by knockback only.
These calculations are independent, so horizontal velocity will behave like on/off. Either player is moving, either player is colliding.

Look how You did it with velocity.y. Nothing is arbitrary set, instead You add gravity force value to knockback value, and it works smoothly.
Do the same thing with velocity.x. Design it so the velocity.x is calculated in one line of code using values from two sources.

Inces | 2022-08-04 14:48

I would appreciate if you could kindly teach me how to implement that. It is beyond my understanding since I am very new to godot.

amaou310 | 2022-08-05 08:19