UnityHFSM
UnityHFSM copied to clipboard
[Bug] Calling fsm.StateCanExit in StateBase.OnEnter does not allow the state to exit
When a state calls fsm.StateCanExit while in its OnEnter method, the call seems to be ignored. The state will never exit. However, if the call is moved inside the OnLogic method, everything works as expected.
Not quite sure if this is intended behavior or not, thus labelling this as an issue for now.
If this indeed is intended behavior, I'd recommend adding a warning to the README and to fsm.StateCanExit XML docs about this.
Example script that showcases the behavior:
using UnityEngine;
using UnityHFSM;
namespace UnityHFSMTest
{
public class TestState : StateBase
{
public TestState() : base(needsExitTime:true) { }
public override void OnEnter()
{
Debug.Log("TestState.OnEnter");
// Calling "fsm.StateCanExit" in OnEnter does not allow the state to exit.
fsm.StateCanExit();
Debug.Log("TestState.OnEnter: StateCanExit called");
}
public override void OnLogic()
{
Debug.Log("TestState.OnLogic");
}
}
/// <summary>
/// This example demonstrates how the calling "StateCanExit" in OnEnter does not allow the state to exit.
/// </summary>
public class UnityHFSMStateCanExitTest : MonoBehaviour
{
private StateMachine _rootFsm;
private void Awake()
{
_rootFsm = new StateMachine();
// ----- States -----
_rootFsm.AddState("StateA",
onEnter: _ =>
{
print("StateA.OnEnter");
},
onLogic: state =>
{
if (state.timer.Elapsed > 1)
state.fsm.StateCanExit();
},
needsExitTime: true
);
_rootFsm.AddState("TestState", new TestState());
// ----- Transitions -----
// Alternate between "state A" and "TestState".
_rootFsm.AddTransition(new Transition("StateA", "TestState"));
_rootFsm.AddTransition(new Transition("TestState", "StateA"));
}
private void Start() => _rootFsm.Init();
private void Update() => _rootFsm.OnLogic();
}
}
Expected output:
The "TestState.OnLogic" debug line would NOT get printed.
Actual output:
The exit call is ignored.
Temporary fix:
If we move the fsm.StateCanExit() call to the OnLogic method, the state is exited as expected: