I’m hoping I’m just having some sort of misunderstanding about how this should work. It’s a bit complex to illustrate but I’ll try to pare it down.
I have a subtree state in a state tree asset, that looks like this, for a basic patrol behavior.
This behavior can operate in one of 2 modes.
- If the AI has a ‘behavior context’ actor, it will move to one of those actors
- Otherwise, the behavior can fall back to an “unguided” patrol, which ultimately just uses GetRandomReachablePointInRadius
[Image Removed]
Note that the expectation here is that if GuidedPatrol fails, it should go to UnguidedPatrol(via the failed transition). GuidedPatrol doesn’t have a condition tied to it, so I can’t rely on the Select Child failed, try next. It runs a task to query and select a patrol destination based on some data fetched through a behavior actor(and does some other stuff related to cooldowns). If no results are found, the task returns failed, which I expect to trigger the transition to unguided, but this is not occurring, and I’m not sure why.
Instead what happens, according to the vislog, is that the state tree oscillates rapidly. I have attached a vislog dump from the oscillating frames.
According to the log, the failure of GuidedPatrol is causing failure transitions to fire from higher up the tree. I can see in the debugger that the FStateTreeExecutionContext::TickTriggerTransitionsInternal is hitting the MaxIterations count of 5, but there’s no indication of that part by looking at the logs that I can see.
According to the log, on one of the frames, it shows Completed subtree ‘Patrol’ from global: Failed.
I’m not sure what constitutes a global: Failed, but the task that is actual failing belongs to a state in a subtree that should be able to process its own failed state, and transition to its sibling Unguided state. The log doesn’t mention UnguidedPatrol at all, despite a very explicit transition to it being present on the GuidedPatrol state, which is what is actually failing, so it’s not even trying to transition to it. Instead, failing from higher up the tree.
[Image Removed]
Here is the snippet that executes the patrol stuff
[Image Removed]
- [Image Removed]
So questions
- Why is Patrol:failed the transition getting taken, and not the GuidedPatrol:failed
- When a state fails, does the entire stack fail? Surely states closer to the failure task, like the owning state itself, should get first opportunity at transitions?
- I’ve disabled the tree failed state on Patrol to no avail.
- What do Tree Failed/Tree Succeeded with respect to linked subtrees?
- Do they just complete that subtree?
- Or do they complete the entire hierarchy, regardless of nested subtree levels.
- If it’s the entire hierarchy, how do you set up a ‘return from this subtree’?
- Are there plans to support debugging Link Assets? I’d like to piece out my state tree, as it’s getting complicated, but losing the debug into those linked states is pretty undesirable.
The only other thing special about Patrol is that it is a linked subtree, and it’s running in an Idle Behavior state, which is also a subtree, so maybe there is some execution quirk with nested linked states that I am not aware of.
According to the StateTree.GlobalTasksCompleteOwningFrame cvar, it looks like in 5.6, completions are only suppose to complete the linked state.
But as a user, I would expect transitions to only bubble up if they are not handled at the leaf state they occur in. Since GuidedPatrol is failing, it should be taking the failed transition in GuidedPatrol. Am I wrong about this?
Thanks in advance.
J