gdquest-demos / godot-3-demos

Dozens of free and open source demos for the Godot game engine, version 3. Head to the link below for newer demos for Godot 4+
https://github.com/gdquest-demos/
MIT License
1.85k stars 975 forks source link

Finite State Machine doesn't enter Walk state after Attacking #59

Open Nikola-Milovic opened 4 years ago

Nikola-Milovic commented 4 years ago

I'm submitting a bug probably. I am maybe wrong, but I tried using the fine state machine in my project and I got a bug where the walk animation wouldn't play if you held down walk keys before attack is finished. That didn't seem right and I thought i changed something poorly. But after I tested it in your example as well it is the same. It's hard to spot without actual animations.

What is the current behavior? You never enter walk animation but you are able to move. So the walk animation is never played.

What is the expected behavior? You will enter walk state after finishing the attack.

Tell us the steps to reproduce the bug, and if possible share a minimal demo of the problem.

Add print() to Walk state enter and to sword animation finished

Brumda commented 3 years ago

The animation is bugged for me even after jumping is finished. The character just floats around in the jumping animation until I change state from Idle to move or the other way around. I would really appreciate it if someone would be able to fix that as I don't how.

NathanLovato commented 3 years ago

I recommend checking these new demos. There's an updated state machine there, for which we also wrote a free guide:

  1. Godot design pattern demos
  2. Godot finite state machine guide
Brumda commented 3 years ago

Thank you, your guides are the only thing that prevents me from falling my programing finals. I downloaded your demo from Godot itself (through templates) and I realized that in your code, you never actually enter the previous state after deleting "previous" from states_stack. So instead of this:

func _change_state(state_name):
    if state_name == "previous":
        states_stack.pop_front()
    else:
        states_stack[0] = states_map[state_name]

    current_state = states_stack[0]
    emit_signal("state_changed", current_state)

    if state_name != "previous":
        current_state.enter()

You need this:

func _change_state(state_name):
        if state_name == "previous":
        states_stack.pop_front()

    else:
        states_stack[0] = states_map[state_name]

    current_state = states_stack[0]
    emit_signal("state_changed", current_state)
    current_state.enter()

It works for your demo because, as said above, your animation stays always the same.