Godot Version
4.5
Question
Two enemies use the same code. Yet only one gets the applied knockback, while the other doesn’t. It’s baffling me.
Code:
class_name CogMan
extends BaseEnemy
const SPPED: int = 2500
const FRICTION: float = 1000
@export var minSightRange: int = 4
@export var maxSightRange: int = 1000
@export var sprite_2d: Sprite2D
@export var hit_box: Hitbox
@export var nav_center: Marker2D
@export var navigation_agent_2d: NavigationAgent2D
func _ready() -> void:
stats = stats.duplicate()
stats.no_health.connect(death)
hurt_box.hurt.connect(_on_hurt_box_hurt)
func _physics_process(delta: float) -> void:
var state = playBack.get_current_node()
match state:
"IdleState": idle()
"ChaseState": chase(delta)
"HurtState": hurt(delta)
func idle():
velocity = Vector2.ZERO
func chase(delta):
var player = get_player()
if player is Player:
navigation_agent_2d.target_position = player.global_position
var nextPoint = navigation_agent_2d.get_next_path_position()
velocity = global_position.direction_to(nextPoint - nav_center.position) * SPPED * delta
sprite_2d.scale.x = sign(velocity.x)
else:
velocity = Vector2.ZERO
move_and_slide()
func hurt(delta):
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
print(velocity)
if velocity == Vector2.ZERO:
await get_tree().create_timer(.1).timeout
playBack.start("IdleState")
move_and_slide()
func get_player() -> Player:
return get_tree().get_first_node_in_group("Player")
func is_player_in_range() -> bool:
var result = false
var player = get_player()
if player is Player:
var distanceToPlayer = global_position.distance_to(player.global_position)
if distanceToPlayer <= maxSightRange and distanceToPlayer >= minSightRange:
result = true
return result
Images of each enemy to show how they are built:
What part of your code shows the knockback?
just relized it should put the base enemy code here as well
class_name BaseEnemy
extends CharacterBody2D
@export var healthDropChance: int = 20
@export var stats: Stats
@export var hurt_box: Hurtbox
@export var animation_tree: AnimationTree
@export var score: int = 100
@onready var playBack: AnimationNodeStateMachinePlayback = animation_tree.get("parameters/StateMachine/playback")
const ENEMY_DEATH_EFFECT = preload("uid://tjmftpenelwk")
const HIT_EFFECT = preload("uid://hi055p03iiak")
const HEALTH_PICK_UP = preload("uid://u2waywyamf5m")
func _ready() -> void:
stats = stats.duplicate()
stats.no_health.connect(death)
if not hurt_box.hurt.is_connected(_on_hurt_box_hurt):
hurt_box.hurt.connect(_on_hurt_box_hurt)
func _on_hurt_box_hurt(hitbox: Hitbox) -> void:
Util.add_effect(self, HIT_EFFECT)
stats.health -= hitbox.damage
velocity = hitbox.knockback_direction * hitbox.knockback
playBack.start("HurtState")
func death():
PlayerInfo.score += score
Util.add_effect(self, ENEMY_DEATH_EFFECT)
if randi_range(0, 100) <= healthDropChance:
Util.add_effect(self, HEALTH_PICK_UP)
queue_free()
This code does the knockback itself
func _on_hurt_box_hurt(hitbox: Hitbox) -> void:
Util.add_effect(self, HIT_EFFECT)
stats.health -= hitbox.damage
velocity = hitbox.knockback_direction * hitbox.knockback
playBack.start("HurtState")
This slows the enemy down
func hurt(delta):
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
print(velocity)
if velocity == Vector2.ZERO:
await get_tree().create_timer(.1).timeout
playBack.start("IdleState")
move_and_slide()
LittleEgg185:
_on_hurt_box_hurt
I assume this handles a signal? If so, I would make sure both enemies are listening for that signal.
i did some debugging and it seems that second enemy velocity won’t be used correctly at all. the velocity gets updated but move and slide is not using it correctly