#Enemy not working
19 messages · Page 1 of 1 (latest)
supply your code for your enemy.
extends CharacterBody2D
Movement
@export var speed := 150
var player_chase := false
var player : Node2D = null
Combat
@export var attack_cooldown := 1.0
@export var attack_range := 80.0
@export var attack_damage := 10
@export var detection_range := 300.0
Animation States
enum AnimState {IDLE, RUN, ATTACK}
var current_anim := AnimState.IDLE
var can_attack := true
var is_attacking := false
Nodes
@onready var sprite := $AnimatedSprite2D
@onready var detection_area := $DetectionArea
@onready var attack_hitbox := $AttackHitbox
@onready var cooldown_timer := $AttackCooldownTimer
func _ready():
add_to_group("enemies")
# Configure collision shapes
if detection_area.get_child_count() > 0:
var shape = detection_area.get_child(0)
if shape is CollisionShape2D and shape.shape is CircleShape2D:
shape.shape.radius = detection_range / 2
# Signal connections
detection_area.body_entered.connect(_on_player_detected)
detection_area.body_exited.connect(_on_player_lost)
attack_hitbox.body_entered.connect(_on_attack_connected)
sprite.animation_finished.connect(_on_anim_finished)
cooldown_timer.timeout.connect(_on_cooldown_ended)
func _physics_process(delta):
if is_attacking:
return # Freeze during attack
handle_movement()
handle_attack()
move_and_slide()
func handle_movement():
if not player_chase or not is_instance_valid(player):
velocity = Vector2.ZERO
set_animation(AnimState.IDLE)
return
var direction = (player.global_position - global_position).normalized()
velocity = direction * speed
# Flip sprite based on direction
sprite.flip_h = direction.x < 0 if direction.x != 0 else sprite.flip_h
# Only set run animation if not attacking
if not is_attacking:
set_animation(AnimState.RUN if velocity.length() > 5 else AnimState.IDLE)
func handle_attack():
if not player_chase or not can_attack or not is_instance_valid(player):
return
var distance = global_position.distance_to(player.global_position)
if distance <= attack_range:
start_attack()
func start_attack():
is_attacking = true
can_attack = false
velocity = Vector2.ZERO
set_animation(AnimState.ATTACK)
# Play attack sound if available
if has_node("AttackSound"):
$AttackSound.play()
func set_animation(state: AnimState):
if current_anim == state:
return
current_anim = state
match state:
AnimState.IDLE:
sprite.play("idle")
AnimState.RUN:
sprite.play("run")
AnimState.ATTACK:
sprite.play("attack")
func _on_player_detected(body: Node2D):
if body.is_in_group("player"):
player = body
player_chase = true
print("Player detected!")
func _on_player_lost(body: Node2D):
if body.is_in_group("player"):
player_chase = false
player = null
print("Player lost")
func _on_attack_connected(body: Node2D):
if is_attacking and body.is_in_group("player"):
if body.has_method("take_damage"):
body.take_damage(attack_damage)
print("Hit player for ", attack_damage, " damage")
func _on_anim_finished():
if sprite.animation == "attack":
is_attacking = false
cooldown_timer.start(attack_cooldown)
# Return to chasing if player still in range
if player_chase and) is_instance_valid(player):
var distance = global_position.distance_to(player.global_position)
if distance <= attack_range:
start_attack()
else:
set_animation(AnimState.RUN)
func _on_cooldown_ended():
can_attack = true
print("Attack ready"
The enemy is getting stuck in the attack state because once is_attacking is set to true, there's no mechanism to set it back to false after the attack animation finishes.
ah so how should i fix it
nevermind; its this:
func _physics_process(delta):
if is_attacking:
return # Freeze during attack```
this returns true always
replace with this:
func _physics_process(delta):
# Always handle movement and attacks
handle_movement()
if not is_attacking: # Only check for new attacks if not already attacking
handle_attack()
move_and_slide() # Always call this for proper physics```
probably change handle_movement() to this aswell:
func handle_movement():
if is_attacking:
# Stop moving during attack but don't return
velocity = Vector2.ZERO
return
if not player_chase or not is_instance_valid(player):
velocity = Vector2.ZERO
set_animation(AnimState.IDLE)
return```
thank you it finally works
no problem.
hi sorry small issue he wont stop attacking even when he should be runnignm do u know how to fix
what do you mean
he is attacking, and moving at the same time? or wont move after attacking like before?
hes attacking and moving at the same time and he kidn ajust bypasses the laws of physics and flys
Make sure your enemy scene has:
A CollisionShape2D for the body
The enemy is on a floor/ground with collision
The DetectionArea and AttackHitbox are properly configured
One moment, Ill just give you the full script.
I changed handle_attack() to only be called when not attacking, horizontal movement should be stopped but not gravity.
Seperated horizontal and vertical velocity so the enemy stops flying
Changed the state flow so it wont try to move and attack.