Blackboard gives no option of creating List<YourCustomScript>

From what I have seen, in the Behavior Graph there is no way of creating a List of a specific Type beside the presets on the blackboard.
E.g. Any ScriptableObject. Workaround would be to reference a Class that has that custom List inside.
Am I missing something?

2 Likes

Hi @NixonAroboX !

Your understanding is correct - weā€™re currently only supporting basic types for list variables created through the Blackboard menu. We would definitely like to extend the selection of types that can be used for lists (including custom types as well), but havenā€™t gotten there yet due to other priorities. Hopefully soon! :slight_smile:

1 Like

I was searching for the same functionality when I found this. The behavior graph package is so close, but just a few missing features like this are really limiting.

Itā€™s nothing thatā€™s too bad, just create a bootstrapper class where you store your custom lists and arrays. You just reference the bootstrapper in the blackboard and youā€™re fine :slight_smile:

I am using behavior graph for our current production title :slight_smile:

1 Like

Thanks for the reply. Iā€™m using the paid asset ā€œBehavior Designerā€, and I was just checking out the new behavior graph package. A few things like this, not being able to assign default values, and not having standard ā€œpublicā€ variables that are only visible in the inspector are disadvantages that will probably keep me from switching over.

That being said the editor performance and UI are much better, and the future for this package could be great. If I wasnā€™t already invested in a different solution Iā€™m sure I could use the behavior graph package with only a few tweaks and workarounds.

I respect that.
Def. keep your eyes open about updates on behavior graph, the team is working very hard from what I can tell. If it is not for you now, it may be after a couple of updates =)!

1 Like

Hey @wyattwilson, thank you for the feedback!

Iā€™d like to attempt to answer some of it:

not being able to assign default values

What do you mean by that? Is it in nodes or Blackboard? Because you can assign default values in both.

  1. Assigning a value in a blackboard variable for the graphā€™s blackboard will show that value as default in the inspector.
  2. In a node class you can assign a default value like the following:

[SerializeReference] public BlackboardVariable Speed = new BlackboardVariable(1.0f);

Please note that if the node was already created it wonā€™t reset to the new value and youā€™ll need to re-add it to the graph or set it manually.

not having standard ā€œpublicā€ variables that are only visible in the inspector

I assume you mean non BlackboardVariable fields in nodes? Iā€™m hoping to tackle that one early Q1 :slight_smile:

Can I ask you to provide me with more blockers and quality of life issues that stop you from moving to this package? Whatā€™s your wishlist? :slight_smile:

Hi @LauraRantonen ,

First of all, thank you for clarifying about the default blackboardvariable values for nodes. I didnā€™t see this mentioned in the documentation, but I like the implementation.

Also to clarify, yes, I was referring to non-blackboard variable fields in nodes. Having all variables in the node description gets very verbose very fast, and not all fields have equal importance or frequency of use, so I look forward to having this option, especially for more complex actions.

On a related node, Iā€™ve noticed a formatting issue where the ā€œstoryā€ doesnā€™t seem to format blackboard variables properly when using multiple lines via ā€œ\nā€. The text does break into a newline, but then when reaching a blackboard variable the text seems to center vertically. (see image) Maybe this is just using the ā€œstoryā€ in an unintended way however.

One of the issues Iā€™ve encountered are how ticks work. I see that I can manually call the ā€œTickā€ method for a behavior graph to update, but is there an intended way to stop the automatic call of ā€œTickā€ every frame? My use case involves many enemy objects, and ones that are of lower importance and higher distance from the player donā€™t need to be called every frame. I suspect I may be able to prevent the automatic calling of ā€œTickā€ by disabling the Behavior Agent component, but I havenā€™t tested this yet.

I am also curious what exactly occurs on a ā€œTickā€. Does the graph execute until it reaches a ā€œrunningā€ status? Upon a nodeā€™s ā€œSuccessā€ does the next node call ā€œOnStartā€ and ā€œOnUpdateā€ that same tick (assuming that "OnStart returns Status.Success)?

I am also curious about the ā€œStatus.waitingā€ behavior. I see that this is occurring while child nodes are being executed according to the documentation, but to me it is unclear exactly what that means. Is this only for use with flow nodes, for example a sequence node returning ā€œStatus.iswaitingā€ while the children are being performed?

Now I may have some bad habits regarding how some nodes are intended to be used since I am coming from a different behavior tree implementation, but are aborts only called once in their sequence? The previous system I used had aborts implemented into its equivalent of ā€œflowā€ nodes, and that abort would be evaluated every update, along with a hierarchical structure of higher priority sequences being able to ā€œstealā€ the execution from lower priority ones. If this sounds convoluted, it is because it is (and it was poorly implemented), but I hope that the advantage of that system can be imagined. Let me give you the example of what I am currently using this system for:

My enemy npcs have a ā€œstunnedā€ state when they have had their ā€˜postureā€™ bar fully depleted (similar to Sekiro). This overrides all other behaviors. So when the variable ā€œisStunnedā€ is true the behavior tree should abort all behaviors being performed and jump to the ā€œisStunnedā€ branch. How should this behavior be handled in the behavior graph? In the previous behavior tree system I was using, the previously mentioned ā€œHierarchical priority abort structureā€ was a very inelegant solution that fit this exact scenario. I am just struggling to determine the intended method for implementing this type of behavior in the behavior graph. I do see potential solutions with custom flow nodes, but hopefully there is an integrated solution.

All of that being said, I decided to start migrating towards the new behavior graph due to its better editor performance and ui. There is a lot that I am impressed by. I really hope that it is widely used because it seems like a significant tool for the vanilla Unity experience. I just hope that the documentation is updated to be as pedantic as I am, and that the examples in the demos are made significantly more complex to show how more advanced behaviors are intended to be implemented.

Thanks for replying and showing interest in my feedback. I am very excited about the potential of this package.

1 Like

Hello @wyattwilson ,

Thank you very much for taking the time to share your feedback :smiling_face:

There is a lot to cover, so I might miss a few bits, donā€™t hesitate to ask for more details!

I think there is a bit of confusion here. We indeed donā€™t support direct ā€œconstantā€ that would allow to display non-BlackboardVariable [SerializeField] type to a node. However it is already possible have a serialized BlackboardVariable not specify the node story ā€“ it will in that case be display in the node inspector:

Looks like something we didnā€™t expected :sweat_smile:
It is true that the node story support rich-text (which is neat to use things like bold and italic). But you are probably the first user trying to use it to multiline. This is not something we want to support as far as I know, as the goal is to let user create to short node instruction that should be short and easy to read. Actually we even have plan to limit the maximum limit of character that a node story can display (or at least limiting the amount of character user can set when creating a new node).

Like you mentionned, you can prevent a graph from running by disabling the Behavior(Graph)Agent component.

Aditionnally, we are working on improving the general lifecycle of BehaviorGraphAgent, and one of the area we would like to improve is the ability to specify the Update method of agents. This way you will be able to choose when they should tick, but also could start implementing Level Of Details mechanism for your BehaviorAgents.

You guessed right, when Tick is called, the graph is going to:

  1. Look if there are nodes to run
  2. If there are, start running them and their child until they all succeed or until one returns Failure/Running/Waiting/ā€¦ (ofc the actual flow mechanism can be complex as some nodes can run in parallel - sequentially)

The Waiting status can be use when a node wait for an external system. It usually means that the node started it and is now either going to:

  • run forever (or until aborted)
  • or is waiting for the system to finish before Awaking itself to then continue execution

A good example of node waiting is the Load Scene. It uses SceneManager to create an async request and wait for completion before resuming the node.

Iā€™m not sure to understand your question. In Behavior, modifiers such as Abort, Restart or even Repeat are always going to affect their child (and underlyings).

This sounds like the priority system that Behavior Tree usually implements. We donā€™t have that ability currently in Behavior but we discussed some of the implication in this thread in case that might be of interest.

That sounds very interesting, I cannot really provide specific guidance as there might be more to consider, but something I usually recommend is to make complex behavior by using an FSM-BT hybrid approach. BT used to evaluate the state of your agent and FSM part to implement state and reaction.

Sounds like you already had a look at the Behavior Demo. Would you have suggestion of what kind of complex scenario you would like to see being covered?

Thanks again for taking the time to provide with such in-depth feedback :+1:

1 Like