How to make my knockback not make the enemy go thorugh walls

Godot Version

4.2.2

Question

When I hit my enemy I want him to be pushed back, howeverr he is now going though walls when that happens.
My code:


var receives_knockback: bool = true
var knockback_modifier: float = 1
var ACCELERATION = 1500
var FRICTION = 60000
var SPEED = 800.0
var SPEEDLESS = 200.0
var loopy = 3
var goofy = 1
var othergoofy = 0
var stop = true
var dizzy = 0
var motion = false
var breaking = false
var motionstart = false
var motionend = false
var death = false
var idle = true
var deathcounter = 4
@onready var rollyaway = $ROLLY
# Get the gravity from the project settings to be synced with RigidBody nodes.
@onready var player = get_parent().get_parent().get_node("Player")
@onready var playerpos = global_position.direction_to(player.global_position)
@onready var rng = RandomNumberGenerator.new()
@onready var my_random_number = rng.randf_range(1, 100)



func _process(delta):
	
	pass

func _physics_process(delta):
	velocity = velocity.move_toward(Vector2.ZERO, 200 * delta)
	move_and_slide()
	if deathcounter == 0:
		death = true
	if death == true:
		queue_free()
	if(player.position.x - position.x) > 0 and stop == true:
		$Sprite2D.flip_h = true
	elif(player.position.x - position.x) < 0 and stop == true:
		$Sprite2D.flip_h = false
	move_and_slide()
	if motion == true and motionend == false and idle == false :
		$AnimationPlayer.play("rollrollypoly")
	elif motionstart == true and idle == false:
		$AnimationPlayer.play("startrollypoly")
	elif motionend == true and idle == false:
		$AnimationPlayer.play("endrollypoly")
	elif breaking == true and idle == false:
		$AnimationPlayer.play("dizzyrollypoly")

	elif idle == true and motionstart == false:
		

		$AnimationPlayer.play("idlerollypoly")
	if rollyaway.is_colliding():
		velocity += rollyaway.get_pushed() * 60000
	if stop == false:
		$Area2D.monitoring = true
		velocity.x += (playerpos.x * SPEED) * delta
		velocity.y += (playerpos.y * SPEED) * delta
		await get_tree().create_timer(2).timeout
		
		
		motion = false
		
		motionend = true
		await get_tree().create_timer(0.45).timeout
		motionend = false
		stop = true
	else:
		$Area2D.monitoring = false
		playerpos = global_position.direction_to(player.global_position)
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
		idle = true
		
		
		await get_tree().create_timer(2).timeout
		idle = false
		motionstart = true
		await get_tree().create_timer(0.50).timeout
		motion = true
		stop = false
		motionstart = false
		
		
		pass


	

func receive_knockback(damage_source_pos: Vector2):
	if receives_knockback:
		var knockback_direction = damage_source_pos.direction_to(self.global_position)
		var knockback_strength = knockback_modifier * SPEEDLESS
		var knockback = knockback_direction * knockback_strength
		
		global_position += knockback 








func _on_hurtbox_area_entered(area):
	if area.is_in_group("Slash") and stop == true:
		
		deathcounter -= 1
		receive_knockback(area.global_position)
	pass # Replace with function body.

Any help would be appreciated!

Probably this is happening because you’re applying your knockback using global position instead use the physics methods like move_and_slide, set global position will teleport your character instead move him, try something like that:

var receives_knockback: bool = true
var knockback_modifier: float = 1
# Create a variable to hold the knockback velocity
var knockback_velocity := Vector.ZERO
var ACCELERATION = 1500
var FRICTION = 60000
var SPEED = 800.0
var SPEEDLESS = 200.0
var loopy = 3
var goofy = 1
var othergoofy = 0
var stop = true
var dizzy = 0
var motion = false
var breaking = false
var motionstart = false
var motionend = false
var death = false
var idle = true
var deathcounter = 4
@onready var rollyaway = $ROLLY
# Get the gravity from the project settings to be synced with RigidBody nodes.
@onready var player = get_parent().get_parent().get_node("Player")
@onready var playerpos = global_position.direction_to(player.global_position)
@onready var rng = RandomNumberGenerator.new()
@onready var my_random_number = rng.randf_range(1, 100)


func _process(delta):
	pass


func _physics_process(delta):
	# Check if you have knockback to compute, if has, apply the knockback
	# using the physics methods and don't proceed for the other checks, 
	# if you need to apply the knockback force for more time, create a timer
	# and use the timeout signal to zero the knockback_velocity variable
	if knockback_velocty.is_zero_approx() == false:
		velocity = knockback_velocity
		move_and_slide()
		knockback_velocity = Vector.ZERO
		return

	velocity = velocity.move_toward(Vector2.ZERO, 200 * delta)
	move_and_slide()
	if deathcounter == 0:
		death = true
	if death == true:
		queue_free()
	if(player.position.x - position.x) > 0 and stop == true:
		$Sprite2D.flip_h = true
	elif(player.position.x - position.x) < 0 and stop == true:
		$Sprite2D.flip_h = false
	move_and_slide()
	if motion == true and motionend == false and idle == false :
		$AnimationPlayer.play("rollrollypoly")
	elif motionstart == true and idle == false:
		$AnimationPlayer.play("startrollypoly")
	elif motionend == true and idle == false:
		$AnimationPlayer.play("endrollypoly")
	elif breaking == true and idle == false:
		$AnimationPlayer.play("dizzyrollypoly")

	elif idle == true and motionstart == false:
		

		$AnimationPlayer.play("idlerollypoly")
	if rollyaway.is_colliding():
		velocity += rollyaway.get_pushed() * 60000
	if stop == false:
		$Area2D.monitoring = true
		velocity.x += (playerpos.x * SPEED) * delta
		velocity.y += (playerpos.y * SPEED) * delta
		await get_tree().create_timer(2).timeout
		
		
		motion = false
		
		motionend = true
		await get_tree().create_timer(0.45).timeout
		motionend = false
		stop = true
	else:
		$Area2D.monitoring = false
		playerpos = global_position.direction_to(player.global_position)
		velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
		idle = true
		
		
		await get_tree().create_timer(2).timeout
		idle = false
		motionstart = true
		await get_tree().create_timer(0.50).timeout
		motion = true
		stop = false
		motionstart = false


func receive_knockback(damage_source_pos: Vector2):
	if receives_knockback:
		var knockback_direction = damage_source_pos.direction_to(self.global_position)
		var knockback_strength = knockback_modifier * SPEEDLESS
		knockback_velocity = knockback_direction * knockback_strength


func _on_hurtbox_area_entered(area):
	if area.is_in_group("Slash") and stop == true:
		deathcounter -= 1
		receive_knockback(area.global_position)
	pass # Replace with function body.
1 Like

It worked! Thanks!