guys i'm having trouble getting my ennemy ai to work as i'm new to godot and game dev in general, it glitches everytime and i don't even no where the problem is to fix it. it's a 2d metroidvania like game and the ai is supposed to patrol chase and attack.
any form of help is appreciated guys, i can also drop the code or the project if someone is willing to take a deeper look to help me
Metroidvania Ennemy AI failed !
For starters you might want to post some examples, your code for an example as well as perhaps a screenshot of your scene hierarchy.
- Edited
Megalomaniak the code may be messed up, but i'm willing to learn and understand. Thank you.
extends KinematicBody2D
const GRAVITY = 15
const SPEED = 40
const CHASE_SPEED = 60
var left = true
var motion = Vector2.ZERO
var is_attacking := false
var can_move := true
var is_chasing := false
var attack_name = 'combo0'
onready var player = get_node('/root/World/Player')
func _ready():
$AnimatedSprite.play('walk')
func _process(delta):
if is_attacking: return
chase_player()
detect_floor()
if can_move and !is_chasing:
move_character()
if motion.x == 0:$AnimatedSprite.play('idle')
else:$AnimatedSprite.play('walk')
if is_chasing:
if motion.x == 0:$AnimatedSprite.play('idle')
else:$AnimatedSprite.play('walk')
func move_character():
motion.x = -SPEED if left else SPEED
motion.y += GRAVITY
motion = move_and_slide(motion,Vector2.UP)
func detect_floor():
if (not $HoleChecker.is_colliding() and is_on_floor() and !is_chasing):
left = !left
scale.x = -scale.x
$HoleChecker.enabled = true
if is_chasing and motion.x !=0:
if motion.x > 0:
$AnimatedSprite.flip_h = true
$Vision.rotation_degrees = 90
$PlayerChecker.rotation_degrees = 0
else:
$AnimatedSprite.flip_h = false
$Vision.rotation_degrees = -90
$PlayerChecker.rotation_degrees = 180
func chase_player():
var direction = (player.position - position).normalized()
if $Vision.is_colliding() and is_on_floor():
is_chasing = true
if is_chasing:
motion.x = direction.x * CHASE_SPEED
motion.y += GRAVITY
motion = move_and_slide(motion,Vector2.UP)
if abs(direction.x) > 0.9998:
is_chasing = false
func attack(attack_name,delay):
can_move = false
$AttackTimer.set_wait_time(delay)
$AttackTimer.start()
$AnimatedSprite.play(attack_name)
is_attacking = true
func _on_PlayerChecker_body_entered(body):
attack(attack_name,1.1)
func _on_PlayerChecker_body_exited(body):
is_attacking = false
attack_name = 'combo0'
func _on_AttackTimer_timeout():
if attack_name == 'combo0' and is_attacking:
attack_name = 'combo1'
attack(attack_name,1.6)
elif is_attacking:
attack_name = 'combo0'
attack(attack_name,1.1)
func _on_AnimatedSprite_animation_finished():
can_move = true
MAyno16 it glitches everytime
Also could you give a description of exactly what and how 'glitches'?
Megalomaniak the problem is the chasing phase and the direction the ennemy is facing. it does seem to work only when it detects me from the left but when it detects me from the right he flips to the other side, and i don't know exactly what part of my code did the problem
- Edited
Have you tried using breakpoints to debug it during runtime?
ps. the video doesn't work for me, but I also have js/script blocking add-on installed on my browser so it could be that I didn't give the necessary privileges to the right thing.
There is a godot behavior tree plugin on github called beehav, which will make your life a lot easier if you could intergrate,it into your exist AI codes.
- Edited
MagickPanda There is a godot behavior tree plugin on github called beehav
You mean Beehave?
Megalomaniak yeah my mistake.
MagickPanda
it was hard to understand how to integrate it into my own project because the developper didn't explain how it actually works. He did demonstrate its usage on his personal project tho. Can you suggest any documentation or tutorial please ?
MAyno16
Just take a look at his tutorial example demo's video here:
In this video's comment area there are also more videos targetting wider audience and newbie godot devs.
- Edited
MagickPanda
Thank you very much but i actually got the code fixed on my own. Nevertheless, i will definitely try Beehave
Here is the Reworked chase code part:
func chase_player():
var direction = (player.position - position).normalized()
if $Vision.is_colliding() and is_on_floor() and !is_chasing:
last_dir = direction.x
is_chasing = true
if is_chasing:
if abs(last_dir-direction.x)>abs(last_dir) and not(flipped):
flipped = true
flipSK()
elif abs(last_dir-direction.x)<abs(last_dir) and flipped:
flipped = false
flipSK()
motion.x = direction.x * CHASE_SPEED
motion.y += GRAVITY
motion = move_and_slide(motion,Vector2.UP)
if abs(direction.x) > 0.9998:
is_chasing = false
func flipSK():
$AnimatedSprite.flip_h = not($AnimatedSprite.flip_h)
$HoleChecker.position.x = -$HoleChecker.position.x
$PlayerChecker.scale.x = -$PlayerChecker.scale.x
$AttackChecker.scale.x = -$AttackChecker.scale.x
$Vision.rotation_degrees = -$Vision.rotation_degrees
MAyno16 That's good to know,you finally got it working.
Ultimately beehave will make ai behaviors more manageable and maintain–able, though plugging it into exist codes can be rather frustrating, I am also trying to use beehave as my game's individual unit AI, and It's taking alot more efforts compare to a primitive state machine stuff, but imo it will pay off in a long run.