We’re excited to announce that Behavior 1.0.15 is now available!
This release delivers the long-awaited ObserverAbort support, a set of quality-of-life improvements for faster iteration and debugging, and important fixes for regressions introduced in recent versions.
ObserverAbort
ObserverAbort is now supported, enabling more responsive and predictable behavior tree execution by aborting running branches when observed conditions change.
Learn how to configure and use ObserverAbort in the manual:
Please note:
- To avoid semantic conflicts with ObserverAbort, the previously named “Abort” node has been renamed to “Fail”.
- A new ConditionalGuardModifier node have been added to provide conditional guard with observer abort support. Please refer to this particular section to learn about how to use it.
Quality of Life Improvements
-
Blackboard overrides in Agent Inspector: Blackboards declared inside behavior graphs are now visible and overridable directly from the Behavior Graph Agent Inspector, making it easier to configure per-agent data without leaving the inspector.
-
Auto-connect debug target in Play Mode: A new option have been added to the Behavior graph editor debug window. When enabled, the debugger will auto-connect to the selected target during Play Mode.
-
Truncated condition display: Added a toggle the truncate option in ConditionalGuardAction.
-
Breakpoints pause without IDE attachment: While in the Unity Editor Play Mode, node breakpoints now pause execution when not attached to an external IDE debugger (previously, breakpoint would be usable when attached to the IDE debugger).
Fixed Regressions
- 1.0.14: Fixed an issue preventing removal of node connections when connected to Conditional Branch or Switch outputs in Behavior Graph.
- 1.0.13: Fixed a NullReferenceException when marking a blackboard variable of enumeration type as Shared.
Changelog
You can review the full changelog here:
Please pay special attention to the “Known Issues” section, as it contains important information about current limitations.
Your Feedback Matters
As always, a big thank you for your continued feedback!
16 Likes
Amazing work, I will try them later, in the meantime I have a QoL request:
Branch node is currently outputting two nodes, true and false, what about having true and false directly on the node itself instead of two big nodes under it?:
Now:
Then:
1 Like
Does this work with shared variables? because I’m trying to override a sprite and seems to not work:
Yep Shared variables are bugged, to add to the known issues 
Thinking about it, would it be use full to know if a variable is shared or not in the inspector?
Oooh, the prioirty abort is exactly what I was needing to fix an issue! I got the notification about the update as I was literally looking at the graph to figure out to fix it.
However I am having an issue. From my understanding this should be logging 000000, but always logs 111111. Am I not understanding or is it not working as intended?
As mentioned here: Introduction to observer-based priority interruption | Behavior | 1.0.15
For pure priority-based interruption, use the Priority Abort node. This node is dedicated to priority interruption and clearly communicates its intent in the graph.
Use Conditional Guard, Conditional Branch, or Repeat While when you need both conditional evaluation and optional observer behavior.
So in your case Abort Lower Priority is not blocking and will only abort when the sibling is running and the condition becomes true.
If you expect 000000 as output, you should use a ConditionalGuard with LowerPriority Abort. Additionally, because LogMessage is executed in less than a frame, the branch will finish executing and the condition will never have time to be checked. I’d recommend to use observer abort with sibling expected to have a running or waiting status.
We put a lot of effort to document the feature with plenty of examples. Any feedback for improvement is welcome. Thank you!
Good call, I did forgot to add the section. They should be the same as previous versions.
Branch node is currently outputting two nodes, true and false, what about having true and false directly on the node itself instead of two big nodes under it?
This is a feature (or limitation depending of your view
) of the tool. They are called floating nodes and they are also used for custom composite nodes.
Does this work with shared variables? because I’m trying to override a sprite and seems to not work:
[…]Thinking about it, would it be use full to know if a variable is shared or not in the inspector?
There is still a bit of work required to refine the shared variable UX. Currently it is not clear which is the source of truth and my opinion is that we should not allow edit of them from the BehaviorGraphAgent (but still somehow show them as readonly at least). Related thread.
Yep Shared variables are bugged, to add to the known issues
Could you please ensure that the variable in the Blackboard asset is exposed?

Seems like override works on exposed variables, BUT the revert command on override variables has some issues, like, it’s not working for me.

Ok, on big graphs this is annoying, probably a rework with the next version of Graph Toolking will probably help with these things
This is kinda expected and this is what I describe as “issue with source of truth”. When you set a shared variable, it will change the instance in the source blackboarb asset. What you do in this case is reverting the Variable instance on the instanced agent, and for shared blackboard variable, it means reverting to the value of the source asset (which is now your new sprite).
However there is indeed a bug, because even if the runtime blackboard now have this new value, the blackboard asset editor shows the previous sprite (because the authoring model is not reflecting the new shared variable). And undo mechanism (not revert on the component) is also not capturing the set value on the source asset.
Realistically, it makes no sense (and is quite confusing and counter-productive) to be able to set a shared variable from an instanced agent variables. So it is probable that a future version will make shared variables read-only on the component (just like in the graph editor blackboard).
Thank you for the valuable feedback 
1 Like
It was indeed a strange behaviour because blackboard was showing the right asset but inspector not, I had to close and re open the editor to fix it.
As you said I would much prefer shared variables to be read only (and the inspector should highlights it very well).
OR if we can decide to edit them, make a pop up menu which tell you: Warning, this is a blackboard shared variable, changing this will change the variable for every BehaviourGraph which use this blackboard variable.
1 Like
We put a lot of effort to document the feature with plenty of examples
Yuup I really appreciate the docs, they are good and the first thing I read!
For pure priority-based interruption
This could be due to a lack of familarity on my part, but this doesn’t ‘mean anything’ to me in relation to using priority abort vs conditional guards. Maybe some additional explaining would help or rewording?
I was looking at the example in the docs and the way I read the “Before” version is that:
If a enemey is detected and the agent has enough health it will attack the enemey.
If not it will check if the agent is low on health and has a health pack. If so it will heal.
The way the “After” version reads to me is that:
Any time the agent’s health is low and has a health pack it will heal
If not it will then attack an enemy any time one is near.
Is this correct?
The behavior I am seeing would mean that in the “After” version, it would always be using a health pack, regardless of the agent was low on health or had one. And none of the other children of the Try In Order would run.
Also worth noting that I already tried having the 000 branch be a repeat node with a child Cooldown node which has the Log 0000 as a child. But the behavior seemed the same, so removed it.
2 Likes
The behavior I am seeing would mean that in the “After” version, it would always be using a health pack, regardless of the agent was low on health or had one.
Yes it is the case, but now I realize that this example is not explicit enough I we should have used a ConditionalGuard node with LowerPriority abort target instead of the PriorityAbort node. This is especially true when comparing “Before” and “After” where before was using ConditionalGuard to trigger the failure.
In this “After” example, my reasoning was that the agent would run all the action but each action would return Failure because their internal action would not be able to succeed (Health is full already, Target is out of range). But using ConditionalGuard (as a Modifier so “Pass & Abort LowerPriority If”) would make that explicit and allow simplification of each actions. Thanks for pointing that out 
Here is a better example from the documentation: Observer abort in Behavior | Behavior | 1.0.15
Edit: I’ve reported the confusion, doc should be updated in the next release.
2 Likes
Oooh, I didn’t realize the ConditionalGuard had new behavior. If I am going to be honest, having the conditional guard change type when it is a child of a sequence node and not stacked with other nodes is a bit confusing and ‘hard to find’. Also means when it is disconnected it loses what was set.
But I am happy to have this functionlity now! Thank you for both adding it, and explaining more! 
Edit: To clarify, I think it would have been easier to use and understand if instead of the ConditionalGuard having an option to abort. The PriorityAbort had a option to be conditional since the option would always be there unlike with the ConditionalGuard. And imo be more inline with how you might want it to work. Right now you have two nodes that end up having a lot of overlap, and as you make a graph you might realize you want to switch between the two (switching 'on or ‘off’ the conditional aspect). But currently that means you would have to redo the whole node.
1 Like
Nice update
Hope to see more QoL improvements!
About the node example using Observer Abort,
is DangerDetected a mistake and should it be EnemyDetected? In before example, there was a case where the character was patrolling and immediately aborted when an enemy was detected, then switched to Chase, right? At the moment the enemy is detected, FailIf is triggered. But in the new example, where is the process being aborted when the enemy is detected?
I haven’t used Run In Parallel before, does it end when all child succeeds? If so, do we still need the FailIf node in the before example?
is DangerDetected a mistake and should it be EnemyDetected?
Yes it is 
I’ll make sure to provide properly updated screenshots for the next release, sorry for the confusion.
I haven’t used Run In Parallel before, does it end when all child succeeds? If so, do we still need the FailIf node in the before example?
Yes, it will end if all child succeeds, however Patrol will never finish (returns Status.Running) and need manual aborting (the “Fail”).