Godot Version
4.3
Question
hi all,
this is my first project in Godot, so i am using it to learn.
I created an enemy with 2 raycasts2d Left and Right. and have the following code to detect the player, measure the distance between the enemy and player and set chasing = true to start chasing the player.
everything works fine except when the enemy is approaching the player from the left side (right raycast) the enemy stops moving and starts flipping directions in its place.
I have checked the following:
- player is on layer 4 and the raycasts layer masks are set to layer 4, disabled parent detection, enabled collision with bodies
- the scene is a characterbody2d->node2d->(raycaslt left, raycast right)
- both characterbody2d and node2d are at layer 3 and set to collide with layer 4 (player)
func detect_rays():
if ray_left.is_colliding():
if ray_left.get_collider().name == "player":
if (enemy_pos.x - player.position.x) <= enemy_detect:
chasing = true
elif ray_right.is_colliding():
if ray_right.get_collider().name == "player":
if (player.position.x - enemy_pos.x) <= enemy_detect:
chasing = true
else:
chasing = false
this is where i am setting the direction of the enemy where i have a variable flip_sprite for enemies with opposite sprite direction (some enemies have left facing images others have right facing images):
i am suspecting that there might be a problem here, but i have went code blind and can’t see where the problem is:
if !flip_sprite:
if player.position.x >= self.position.x:
direction = 1
enemy_anim.flip_h = false
else:
direction = -1
enemy_anim.flip_h = true
else:
if player.position.x >= self.position.x:
direction = 1
enemy_anim.flip_h = true
else:
direction = -1
enemy_anim.flip_h = false
Does
else:
if player.position.x >= self.position.x:
direction = 1
enemy_anim.flip_h = true
else:
direction = -1
enemy_anim.flip_h = false
need to be
else:
if player.position.x >= self.position.x:
direction = -1
enemy_anim.flip_h = true
else:
direction = 1
enemy_anim.flip_h = false
thank you for the reply, if the player position is more than the enemy position on the x axis (enemy approaching from the left, ie right raycast2d) then direction needs to be positive 1 so that when velocity.x = direction * speed is called the enemy moves right towards the player. if it was -1 like below it will move in the opposite direction of the player.
i have the x axis is from 0 to 1152px
if player.position.x >= self.position.x:
direction = -1
enemy_anim.flip_h = true
the weird thing is that I have the code checked multiple times, collisions as well, layers, everything. its either a bug or i just need some rest that i can’t see the error.
I was hoping its a really easy fix that i am missing and another eye will help see it
I saw a few codes using
move_towards
global_position
i guess i’ll have to read the documentation tomorrow and familiarize myself with those functions
Can you upload it anywhere or give me instructions for a minimal project to replicate? Re-reading it, could the ray casts be interfering? The order of the if statements suggest that maybe they could be it.
sure,
this is the latest edited physics function that deals with the enemy movement and the detect rays and attack rays. the detect_rays() and attack_rays() return boolean value attacking and chasing. i manually edited the reversed sprite images to get rid of flipping them separately.
func _physics_process(delta):
if enemy_damage < max_enemy_damage:
enemy_damage = enemy_damage * Game.mob_damage_factor * Game.player_level
else:
enemy_damage = max_enemy_damage
if player.position.x >= self.position.x:
direction = 1
enemy_anim.flip_h = false
else:
direction = -1
enemy_anim.flip_h = true
velocity.y += gravity * delta
detect_rays()
attack_rays()
if player_damaged:
temp_player_health = Game.player_hp - enemy_damage
Game.player_hp = temp_player_health
player_anim.play("damaged")
else:
player_anim.play("run")
if chasing and !enemy_dead:
enemy_speed = enemy_run
else:
if !enemy_dead:
enemy_speed = enemy_walk
else:
enemy_speed = 0
if attacking:
enemy_anim.play("attack")
elif enemy_dead:
enemy_anim.play("dead")
else:
enemy_anim.play("run")
velocity.x = direction * enemy_speed
move_and_slide()
func detect_rays():
if ray_left.is_colliding():
if ray_left.get_collider().name == "player":
if (enemy_pos.x - player.position.x) <= enemy_detect:
chasing = true
elif ray_right.is_colliding():
if ray_right.get_collider().name == "player":
if (player.position.x - enemy_pos.x) <= enemy_detect:
chasing = true
else:
chasing = false
func attack_rays():
if attack_ray_left.is_colliding():
if attack_ray_left.get_collider().name == "player":
if (enemy_pos.x - player.position.x) <= attack_range:
attacking = true
player_damaged = true
elif attack_ray_right.is_colliding():
if attack_ray_right.get_collider().name == "player":
if (player.position.x - enemy_pos.x) <= attack_range:
attacking = true
player_damaged = true
else:
attacking = false
player_damaged = false
the detect_rays() and attack_rays() return boolean value
It looks like internally they are setting values, but they are void returning functions. Without the whole project, showing all the affected variables and how the scripts link, I don’t know how I can help. e.g is player_damaged a local or a global variable.
If you’re happy to share the whole thing I’ll gladly play with it to try to help. If not I don’t think I can help. perhaps someone more knowledgeable then me may know more.
thank you for your help. i changed the function entirely using vector2d variables and everything works now.
1 Like