func _can_switch(transition: FrayStateMachineTransition) -> bool:
return (
transition.switch_mode == FrayStateMachineTransition.SwitchMode.IMMEDIATE
or (transition.switch_mode == FrayStateMachineTransition.SwitchMode.AT_END
and is_done_processing())
)
should be
func _can_switch(transition: FrayStateMachineTransition) -> bool:
return (
transition.switch_mode == FrayStateMachineTransition.SwitchMode.IMMEDIATE
or (transition.switch_mode == FrayStateMachineTransition.SwitchMode.AT_END
and get_state_current()._is_done_processing_impl()) # <-------
)
I based my correction on this enum in FrayStateMachineTransition :
enum SwitchMode{
IMMEDIATE, ## Switch to the next state immediately.
AT_END, ## Wait for the current state to end, then switch to the beginning of the next state.
}
The current implementation use the FrayRootState's _is_done_processing_impl() function, which basically check if we are at the end state of this root state. But FrayRootState didn't check the current state's _is_done_processing .
combat_sm.add_situation("grounded",FrayRootState.builder()
.start_at('standing')
.add_state('dash',dash_state) # custom FrayState that override _is_done_processing to wait for a timer on entering the state.
.transition_sequence('standing','dash',{sequence="dash"}) # FraySequenceBranch for double tapping
.transition("dash",'standing',{switch_mode = FrayStateMachineTransition.SwitchMode.AT_END,prereqs=[on_floor]})
I also changed root_state.gd:lign 430 for this
func _goto(to_state: StringName, args: Dictionary) -> void:
if _ERR_INVALID_STATE(to_state): return
var prev_state_name := _current_state
var target_state: RefCounted = get_state(to_state) <----
if target_state != null && not _current_state.is_empty(): <----
get_state(_current_state)._exit_impl() <----
_current_state = to_state
get_state(_current_state)._enter_impl(args)
transitioned.emit(prev_state_name, _current_state)
This correctly call _enter_impl() and _exit_impl(), previously it was exiting the target_state before entering it in any transition.
Root state.gd lign 434
should be
I based my correction on this enum in FrayStateMachineTransition :
The current implementation use the FrayRootState's _is_done_processing_impl() function, which basically check if we are at the end state of this root state. But FrayRootState didn't check the current state's _is_done_processing .
I also changed
root_state.gd:lign 430
for thisThis correctly call _enter_impl() and _exit_impl(), previously it was exiting the target_state before entering it in any transition.