NodeCanvas Forums › Support › FSM state checking its exit transition condition before executing its action?
Tagged: Action, condition, FSM, Order, Transition
Hello,
I have a FSM with a state where I’m performing a single custom action task, then waiting for a custom condition task to return false (checking continuously). For some reason, the OnCheck()
method for the condition is firing before the OnExecute()
method for the action. This doesn’t happen every single time – it seems to have a 50/50 probability of happening. This becomes problematic for any states where its exit condition would be one value if it gets checked first, or another value if its action executes first. I would expect a state’s first action to always execute before any of its exit conditions are checked. Is this a bug?
Here’s my custom tasks. I’m aware that for this specific action I could just wait for the state to complete rather than continuously checking the condition, but this is just an example of the issue.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public class PlayVoiceOver : ActionTask { [RequiredField] public VoiceOverContainer voiceOver; protected override string info { get { return string.Format( "Plays {0}'s voice-over clip", voiceOver == null ? "[NULL]" : voiceOver.name); } } protected override void OnExecute() { Debug.Log("Execute action"); VoiceOverControl.Instance.Play(voiceOver); VoiceOverControl.Instance.PlaybackComplete += OnVoiceOverPlaybackComplete; } private void OnVoiceOverPlaybackComplete() { EndAction(true); if (VoiceOverControl.Instance != null) { VoiceOverControl.Instance.PlaybackComplete -= OnVoiceOverPlaybackComplete; } } } public class IsVoiceOverActive : ConditionTask { protected override string info { get { return "a voice-over is currently active"; } } protected override bool OnCheck() { Debug.Log("Check condition"); return VoiceOverControl.Instance.IsVoiceOverActive; } } |
Here’s part of my editor log showing the Debug.Log from the condition logging before the one from the action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Check condition UnityEngine.DebugLogHandler:Internal_Log() UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) UnityEngine.Logger:Log(LogType, Object) UnityEngine.Debug:Log(Object) Game.StateMachine.IsVoiceOverActive:OnCheck() (at Assets/Game/Scripts/StateMachine/Conditions/MediaConditions.cs:33) NodeCanvas.Framework.ConditionTask:CheckCondition(Component, IBlackboard) (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Tasks/ConditionTask.cs:70) NodeCanvas.StateMachines.FSMState:CheckTransitions() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSMState.cs:170) NodeCanvas.StateMachines.FSMState:Update() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSMState.cs:148) NodeCanvas.StateMachines.FSM:OnGraphUpdate() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSM.cs:127) NodeCanvas.Framework.Graph:UpdateGraph() (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Graphs/Graph.cs:714) ParadoxNotion.Services.MonoManager:Update() (at Assets/External/ParadoxNotion/CanvasCore/Common/Runtime/Services/MonoManager.cs:64) (Filename: Assets/Game/Scripts/StateMachine/Conditions/MediaConditions.cs Line: 33) Execute action UnityEngine.DebugLogHandler:Internal_Log() UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) UnityEngine.Logger:Log(LogType, Object) UnityEngine.Debug:Log(Object) Game.StateMachine.PlayVoiceOver:OnExecute() (at Assets/Game/Scripts/StateMachine/Actions/MediaActions.cs:109) NodeCanvas.Framework.ActionTask:ExecuteAction(Component, IBlackboard) (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Tasks/ActionTask.cs:114) NodeCanvas.Framework.ActionList:OnUpdate() (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Tasks/ActionList.cs:107) NodeCanvas.Framework.ActionTask:ExecuteAction(Component, IBlackboard) (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Tasks/ActionTask.cs:116) NodeCanvas.StateMachines.ActionState:OnUpdate() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/Nodes/ActionState.cs:44) NodeCanvas.StateMachines.ActionState:OnEnter() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/Nodes/ActionState.cs:41) NodeCanvas.StateMachines.FSMState:OnExecute(Component, IBlackboard) (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSMState.cs:136) NodeCanvas.Framework.Node:Execute(Component, IBlackboard) (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Graphs/Node.cs:295) NodeCanvas.StateMachines.FSM:EnterState(FSMState) (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSM.cs:193) NodeCanvas.StateMachines.FSMState:CheckTransitions() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSMState.cs:171) NodeCanvas.StateMachines.FSMState:Update() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSMState.cs:148) NodeCanvas.StateMachines.FSM:OnGraphUpdate() (at Assets/External/ParadoxNotion/NodeCanvas/Modules/StateMachines/FSM.cs:127) NodeCanvas.Framework.Graph:UpdateGraph() (at Assets/External/ParadoxNotion/CanvasCore/Framework/Runtime/Graphs/Graph.cs:714) ParadoxNotion.Services.MonoManager:Update() (at Assets/External/ParadoxNotion/CanvasCore/Common/Runtime/Services/MonoManager.cs:64) (Filename: Assets/Game/Scripts/StateMachine/Actions/MediaActions.cs Line: 109) |
Here’s a picture of my FSM, as well as the state and transition in question.
I’m using Unity v2018.3.3f1 and NodeCanvas Framework v2.91.
Hello,
Hmm. Code wise, “OnExecute” is always called before any transition condition “OnCheck” and I’ve just double checked for any possible bugs. I think the problem might lie with the event registration/unregistration here. Unfortunately I was not able to replicating the problem though :(.
Would it be possible for you to please send me a small replication project showcasing this problem you are facing to (support_AT_paradoxnotion.com) ?
Thank you in advance.
Join us on Discord: https://discord.gg/97q2Rjh
Hmm, yup, it does seem to be the event subscription + callback that was causing this to happen. I just emailed you a Unity project with a reproduction anyways!