0 votes

I have a hurt function of the enemy, which will be called whenever the player hit the hurt box and then play a specific animation based on the player position (I use the animationTree node with animationBlendState2D inside the animationBlendTree in order to play the animations btw).

My goal is simple, play the hurt animation based on the player location, but comes up the problematic when the player changes his self position while the animation is still playing, which will make the animationTree play over again another hurt animation from the beginning because the player position is changes.

Pardon me, maybe the codes can summarize it better:

is_hurt = false

enum{
HURT
}

func _process(delta):
match state:
    HURT:
        hurt_state()

func _physics_process(delta: float) -> void:

 if is_dead == false:
    knockback = knockback.move_toward(Vector2.ZERO, 200 * delta)
    knockback = move_and_slide(knockback)
    if is_hurt == false:
        if is_attacking == false:
            if _player != null:
                state = MOVE
                #etc (ask for more detail)

        if ! is_attacking && position.distance_to(player.position) < attack_distance:
            is_attacking = true

        if is_attacking == true:
            state = ATTACK
            #etc 

    if is_hurt == true:
        anim_tree.set("parameters/Hurt/hurt/blend_position",position.direction_to(player.position).normalized())
        state = HURT

 if is_dead == true:
    #etc
    state = DEATH
velocity = move_and_slide(velocity)

func _on_Hurtbox_area_entered(area): 
 start.health -= area.damage
 knockback = area.knockback_vector * 250
 hurtbox.create_hit_effect()
 is_attacking = false
 is_moving = false
 is_hurt = true

func hurt_state():
 $Sprite.visible = true
 $Sprite2.visible = false
 anim_tree.set("parameters/Hurt/TimeScale/scale", 1.25)
 state_machine.travel("Hurt")

func is_hurt_timeout():
 is_hurt = false

To my way of thinking, the way those functions work, when the player hit the hurtbox, is_hurtwill = true in order to change the state to HURT (hurt_state()). Further more, on the hurt_state() function, the animationTree will be called with the code statemachine.travel("Hurt"). When the animation is finished, is_hurt_timeout() will be actived and return is_hurt equal to false.

As you can see, if the player change himself position, for instance, runs from right to left of the enemy when the animation hasn't play to an end, because the animationState is looking at player location, as a result, the animationTree will play another animation (hurt left) from the beginning, if the player run around the enemy, the function is_hurt_timeout() at the last frame won't be called and the animations will be played for eternity.

Hope that would make up your mind and obviously, very sorry for my horrible English. It would be great if you guys could let me know anything that you are still struggle about, I would love to answer all of them, at the end, hope you have a wonderful day.

Godot version godot 3.3
in Engine by (54 points)

1 Answer

0 votes

Create a boolean (true / false) and then have it change from true to false when the animation is triggered. so the logic will be only play the animation when player is in position and the boolean is true. When the animation finishes change the boolean back to true again.

by (1,685 points)

Can you write the codes example pls, I don't really know how to make it triggered when the player is at the right position, sorry for the inconvenient.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.