Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | salbert |
So I’m following a Youtube tutorial, and I’ve set up player character as a KinematicBody2D with a simple state machine and AnimationPlayer that has an animation for each State/direction combination the character can be in (AttackUp, AttackRight, RunDown, IdleLeft, etc.).
Basically, if the player hits space, he enters the attack state and goes into the ATTACK state in _physics_process(). Inside the attack_state() method, an AnimationTree plays the appropriate attack animation in the AnimationPlayer.
During each attack animation(Attack Up, Attack Down, Attack Left, Attack Right), I have a track that calls a method named attack_animation_finished() when the animation is done. This method changes the player state back to MOVE.
(In the move_state function, the state gets changed to ATTACK if the player presses the space bar. I would paste it in but it doesn’t format in very readable manner.
func _physics_process(delta):
match(state):
MOVE:
move_state(delta)
ROLL:
pass
ATTACK:
attack_state()
func attack_state():
print("Inside attack_state()")
velocity = Vector2.ZERO
animation_state.travel("Attack")
func attack_animation_finished():
print("Inside attack_animation_finished()")
state = MOVE
I put in print() statements to both attack methods to illustrate what I’m talking about.
As you can see, the AnimationPlayer only calls the method once. However, when I play the game and attack, this happens:
The method is being called twice for some reason.
Now, I don’t really understand why the first print() statement is being called so many times either. I assume it has something to do with the length of the animation? I can wrap my head around that, but I can’t understand why the second print() statement is executing twice.
The code for this method clearly sets the state back to MOVE, so it shouldn’t be making a second pass. Regardless, the game is set up so that the only way the method can be called is through the AnimationPlayer, and the AnimationPlayer can only play it if attack_state() is called!
This isn’t causing any actual bugs or weird behaviors at all, it’s just something that I noticed when I was debugging my animations. It however is very weird to me. Why is my AnimationPlayer calling this method twice?
Does it have something to do with the fact I’m playing these animations by using an AnimationTree?
Now, I don’t really understand why the first print() statement is being called so many times either.
It’s being called so many times because the _physics_process()
function is called every time the physics calculations are done. Depending upon your hardware, this is several times a second.
Ertain | 2020-06-14 14:52
I understand that, but why is attack_animation_finished() being called twice? The method clearly changes the state to MOVE and, not only that, but the only way to get to that method is through the attack_state() method, so if attack_animation_finished() were to print twice, wouldn’t it require for a second pass of attack_animation(), which would another series of “Inside attack_state()” messages in the output window?
salbert | 2020-06-14 16:52
Maybe there’s some function which is getting called faster than the _physics_process()
function. Is some of this code tied to the _process()
function? Maybe that’s a bit faster than _physics_process()
?
Ertain | 2020-06-14 19:08
So after using the debugger, I was able to pinpoint the exact moment it goes back to attack_animation_finished(). It was right after the _process() callback in my Global singleton script (That’s the only script in my game that uses _process() right now). WHY it goes directly from _process() to attack_animation_finished(), I have no idea. Right now, I (as a Godot novice) am thinking it is somehow related to the AnimationTree that is calling attack_animation_finished(). Some people have told me it’s better to use a signal for that, so maybe I’ll try that again (I tried before, but for some reason it was causing my game to freeze. I’ll probably try again with the debugger to see what was causing that).
salbert | 2020-06-14 23:46
maybe it happen when you do diagonal attack e.g. right + up , both animation attack state get called and when finish it called twice
ruruarchy | 2020-06-15 08:38
If you ever find a satisfactory answer to this I’d love to know. I followed HeartBeast’s tutorial as well and based a lot of my enemies’ actions on using the call_method
trick (because there’s no other way to know when an AnimationTree
’s animations are done playing…), and my functions are getting called 3-4 times. I’m experiencing weird behavior which might not be that, but I also have other lines of code like timers and such packed into that end-of-animation method call, so I’d rather it not get called several times.
gdscrub | 2020-12-11 22:08
_process() function makes the situation worse, getting called 3-4 times.
songun2021 | 2021-02-09 20:36
I found that calling the script 0.1-0.2 seconds before the end of the animation instead of right at the end relieved a lot of my issues.
gdscrub | 2021-02-15 13:39