From fe2f89e57ef860a8db57af42ff5e6e96deae641b Mon Sep 17 00:00:00 2001 From: groug Date: Tue, 14 Feb 2023 16:53:42 +0100 Subject: [PATCH] add add_states, more doc --- README.md | 32 ++++++++++++++++++++++++++++++-- state_machine.gd | 5 +++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c6859b4..86f5748 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,35 @@ # Description -TODO +I wanted to just use a state machine purely in GDscript, as simply as possible, but with states, transitions, hooks, and conditions/triggers to change states + +- States: the FSM will always be in a state. It will change to another state with the transitions, following the first transaction, having the current state as a source, that matches the conditions/trigger +- Transition: a transition will allow the FSM to change from one state to another when, at each update + - The transition is fully matched the (optional) trigger has been called + - The (optional) conditions has all been met + - A transition is composed of + - A state source + - A state destination + - An optional list of conditions + - An optional trigger +- Transition source: in order to reduce the amount of code to type for transitions, there are some helpers. source can be a string (STATE), or it can be an array: + - STATE: any known state (the easy one) + - "*": all the states (including the destination) + - ^STATE: all the states but STATE. e.g. "^hurt" => it will match, for source, all the states except "hurt" + - -STATE: remove STATE from the previous states added (when source is an array). e.g. ["*", "-idle", "-hurt"] => it will match, for source, all the states except "idle" and "hurt" +- Trigger: a transition can be mapped to 0 or 1 trigger. A trigger is emitted by calling the "trigger" method, and the trigger will be treated at the next update and then forgotten +- Condition: a condition is just the callback of a method returning a boolean. It can be the name of the method, or it can prefixed by "!" to get the reverse boolean + +# TODO +- Maybe optimize the whole thing + # How to use -- Add a Node2D node named "StateMachine" with the script state_machine.gd +- Add it to your project : https://docs.godotengine.org/en/stable/tutorials/plugins/editor/installing_plugins.html#enabling-a-plugin +``` + mkdir -p addons + cd addons + git submodule add ssh://git@git.abxy.fr:212/groug/godot_simple_state_machine.git +``` + +- Add the custom StateMachine node (name it "StateMachine" for the purpose of the example) - Initialize the states, initial state and conditions: ``` $StateMachine.add_state("idle") diff --git a/state_machine.gd b/state_machine.gd index 8f7543e..63f5440 100644 --- a/state_machine.gd +++ b/state_machine.gd @@ -72,6 +72,11 @@ func add_state(name): if _states.count(name) == 0: _states.append(name) +func add_states(states): + for state in states: + if _states.count(state) == 0: + _states.append(state) + func set_init_state(name): _change_state(name)