I have an enemy in my RPG game but if the player walks close of him, he make distance between him and the player.`

Godot Version

4

Question

`
The distance that the enemy makes is equal to the detection area radius

Here is the enemy script

extends CharacterBody2D

var current_state = IDLE
var speed = 60
var player_chase = false
var player = null
var direction = Vector2.RIGHT

var health = 80
var player_in_attack_zone = false
var roaming = true
var can_take_damage = true
var enemy_alive = true

enum {
IDLE,
NEW_DIRECTION,
MOVE
}

func _ready():
pass

func _process(delta):
if Global.game_started == true:
deal_with_damage()
uptade_health()
if enemy_alive == true:
if roaming :
match current_state:
IDLE:
pass
NEW_DIRECTION:
direction = choose([Vector2.RIGHT, Vector2.UP, Vector2.LEFT, Vector2.DOWN])
MOVE :
move(delta)

		if player_chase : 
			position += (player.position - position) / speed
			if Global.player_alive == false:
				player_chase = false
			$AnimatedSprite2D.play("walk")
			if (player.position.x - position.x) < 0 :
				$AnimatedSprite2D.flip_h = true
			else :
				$AnimatedSprite2D.flip_h = false
		else :
			$AnimatedSprite2D.play("idle")

func _on_detection_area_body_entered(body):
player = body
if Global.player_alive == true:
player_chase = true
else:
player_chase = false

func _on_detection_area_body_exited(body):
player = null
player_chase = false

func enemy():
pass

func _on_enemy_hitbox_body_entered(body):
if body.has_method(“player”):
player_in_attack_zone = true

func _on_enemy_hitbox_body_exited(body):
if body.has_method(“player”):
player_in_attack_zone = false

func deal_with_damage():
if player_in_attack_zone and Global.player_current_attack == true :
if can_take_damage == true and health != 0:
health -= 20
$damage_cooldown.start()
can_take_damage = false
print("slime health = ", health)
if health <= 0:
health = 0
enemy_alive = false
$AnimatedSprite2D.play(“death”)
await get_tree().create_timer(1).timeout
self.queue_free()

func uptade_health():
var healthbar = $healthbar
healthbar.value = health

if health >= 100:
	healthbar.visible = false
else :
	healthbar.visible = true

func _on_damage_cooldown_timeout():
can_take_damage = true

func choose(array):
array.shuffle()
return array.front()

func move(delta):
if !player_in_attack_zone:
position += direction * speed * delta

func _on_wait_time_timer_timeout():
$wait_time_timer.wait_time = choose([0.2, 0.5, 1, 1.5])
current_state = choose([IDLE, NEW_DIRECTION,MOVE])

what is the problem here?
you failed to make it make a distance to the player with this code?

No. I wan’t the enemy to chase the player, but the enemy make a distance with the player when the player walk next to him, and this distance is equal to the radius of the enemy’s detection_area. I don’t know why but, in addition to that, as soon as the enemy appears, he heads towards the center of the map. It’s really weird

I would like to show you a video of the game so that you can understand the problem but when I want to import one, it tells me that this type of file is not authorized

try check the sprite position of this scene, either the player or the enemy, the node scene’s sprite and child shall be 0,0 position, else its position looks offset’d

Okay i’ll try but it’s not a visual problem,the problem is that the enemy is supposed to chase the player, but if the sprite was offset it would at least play the animation, but it doesn’t

I think this is the problem:

position += (player.position - position) / speed

Try multiply instead of dividing for example position += (player.position - position) * 0.1
You might also need to normalize the vector: position += (player.position - position).normalized() * 0.1

What means “normalize”? What does it change?

If you use two different positions, put them into a normal equasion without the “normalized” method, it can cause inconsistent enemy behaviour.
This would obviously only occur if the position changes.

Using normalized basically scales down the vector to a value of 1.
This might sound complicated, but for more help, just look into the presentation

I tried and thank you very much it works ! But the enemy don’t chase the player… I made some other changes for make sure that the enemy don’t chase any other object :

func _on_detection_area_body_entered(body):
	if body.has_method("player"):
		player = body
		if Global.player_alive == true:
			player_chase = true
		else:
			player_chase = false


func _on_detection_area_body_exited(body):
	if body.has_method("player"):
		player = null
		player_chase = false

So now can somebody help me to make the enemy chase the player?

and here is a video of my game :


so as you can see the enemy don’t chase the player but he play the animation as if he were
the enemy is just walking very slowly to the right

1 Like

I finally used pathfinding to make the enemy chase the player and it works !!!

(Thank you for 1.3k views)

i had the same problem becuase my guy wasnt on the dot make sure in the player sceen the player is in the top right conor of thr screen this:


not this:

basicly make sure the collision and sprite is on the char body 2d @tsukidraw36

Yes everything was already well centered. Thank you anyway