Hello, dear Unity Developers!
Some time ago in this post you really helped me to fix issues with the slow rate update for TryInOrder and Sequence nodes: Slow Update Rate in the Behavior Graph
Thank you again for this help, it was very useful and because of this help our team decided to not leave the Behavior Graph (because you literally provided us a solution on a major bug in the Behavior Graph before the official fix).
But unfortunately, I spotted a bug of the same kind with Subgraph running. Below I will present you an example. The example is not real, it’s just to explain the issue.
Here are the details:
Let’s imagine that we have a Graph with the next sequence:
When we run the “ProcessIdle” Subgraph, we know what we are doing, we are ready for this Subgraph to take responsibility for the flow before the IsIdle variable in the Animator becomes false.
Now, let’s see what happens in the ProcessIdle Subgraph:
As you can see, a complex graph is present here. It’s not just a sequence, it’s a composition of sequences, conditions, modifiers, and actions. From the top to the bottom they work perfectly, they do exactly what I need.
But the problem arises when we come to the very bottom point - the Success node (it’s just an Action that returns Status.Success in the OnStart()).
What would you expect from the Graph when we reached the Success node? I would expect it to return Success → Exit the Subgraph → Set the IsIdle of the Animator to false in the Root Graph.
But unfortunately, this is not what happens, at least, not within 1 frame. I deeply debugged the class BehaviorGraphModule and noticed one interesting thing: the more complex your Subgraph, the longer you need to wait to exit it. By more complex I mean a lot of Sequences, Modifiers, and Conditions go one after another and this process repeats. And when I pause the editor, and see that I reached the Success node, but it still takes about 6 frames to exit the Subgraph, I have a desync in the logic and animations. The animation must already be non-Idle, but IsIdle is still true because it takes 6 frames to exit the Subgraph despite the fact that its work is already done.
This happens because when the flow is finished in the Subgraph, it will go backwards from the Success node to the OnStart node to exit the Subgraph. I am not sure why this happens, why we need to approve all the previous nodes because if we already reached the Success node at the bottom, that means all the nodes above already returned Success. Maybe it’s needed to clear arrays in the BehaviorGraphModule class instance, but I think it’s possible to somehow refactor the code to make it not be dependent on the complexity of the Graph.
But debugging of the BehaviorGraphModule.cs shows that when we return the Success node, we return Status.Success → we skip the frame and go to the previous node - Modifier “Wait For Any” - returned Success → we skip the frame and go to the previous node - Sequence with conditional guard - returned Success → we skip the frame and go to the previous node - Modifier “Repeat Until Success” - returned Success → And so on.
Dear Unity Developers, thank you that you helped me previously, but while you are fixing this bug (and I am not sure it’s fast), could you please suggest me a workaround?
Maybe it’s possible somehow to instantly exit the Subgraph and clear the m_RunningNodes and ProcessedNodes?
Maybe in the Tick() method of the BehaviorGraphModule.cs we can modify a bit the part with the “if (status != Status.Running) {…}” block? Right now we end the current node, call the “node.AwakeParents()” and then just wait for the next frame. Maybe we could keep the going backward within the same frame instead of just calling “node.AwakeParents()”?
Please help me with the workaround if you can.
Platform: Windows 10
Behavior Version: 1.0.7
Unity Version: 6000.0.25f1
Thank you very much!