I'm trying to implement a mechanic which detects "hard falls" vs "soft falls" and on "hard falls" locks the player's movement while the landing animation plays. I have built a state-machine and an animation tree.
The "falling" state uses the speed just before landing to decide whether to switch to a "hard landing" state or a "soft landing state", and either way it uses the .travel() method on the AnimationNodeStateMachinePlayback to change to the landing animation. The animation plays, but the state ends up switching the "grounded" state before animation finishes. This makes the movement-lock unlock so quickly that it is imperceptible. I put beeping sounds in the function to help troubleshoot, and you can clearly hear the on_exit() beep before the landing animation finishes. I also put in a timer which counts how long the program is in the landing state, and it returns a number between 14 and 17 milliseconds each time; however, the animation has 3 frames each played for 0.1 seconds.
I don't understand why the signal would trigger before the animation actually completes.
"`
extends State
class_name HardLandingState
@onready var grounded_state: State = $"../Grounded"
var start: float
func on_enter():
start = Time.get_ticks_msec()
$"../../Beep".play()
can_move = false
func on_exit():
$"../../Beep".play()
playback.travel("move")
print(Time.get_ticks_msec() - start)
func _on_animation_tree_animation_finished(anim_name):
if anim_name == "landing":
next_state = grounded_state
`"