Hello,
In my game, characters are all identical at design-time (they all come from the same prefab) but have several ScriptableObjects that define their identities when the game starts. For example, one character may be a thief, another may be a named character, a third one may be a guard etc. I want them all to have different behaviors that depend on their identities but also on the current level because the current level tells a story involving the player and different levels mean different stories to tell. One behavior for a character in a level might become irrelevant for the same character in the next level so not all are reusable and that's okay.
For example, a named character may need to come to the player to initiate a conversation, and depending on the outcome of that conversation may give a quest or not. This would be handled by an external Behavior Tree that would be useful only for this level and this character.
To do this, my idea would be to have a very simple high-level skeleton Behavior Tree running a Parallel node under a Repeater, and under that Parallel node a single Behavior Tree Reference which list of external Behaviors would be calculated once when the level starts. I could also have three BT components instead of one. One of them would run the tasks in parallel, another in sequence and another with a selector. I'm not entirely decided on that yet.
So I have a few questions about this approach.
Here is what that simple skeleton tree looks like at design-time:
Don't pay too much attention to the names of the external behavior trees; What's in them, what they do and how they do it is not relevant to this post.
The list of External Behaviors in the Behavior Tree Reference is currently filled by hand but I want to fill it automatically from data gathered from different sources, before the Behavior Tree Reference is consumed and replaced by the instantiated External Behavior Trees. How can I reference the Behavior Tree Reference in my code and fill its list before it instantiates the trees in said list?
My second question would be about what happens next. When the Behavior Tree Reference is replaced by instances of its contents, the resulting sub-trees all overlap each other (except the first one), like this:
But what I want it to look like is this:
(I know the order of the nodes does not match the list displayed in the first screenshot, this is just for the sake of example. I just dragged the five nodes manually.)
Not only the order in which the nodes are placed under their parent is supposed to be important, but debugging this would be too cumbersome because if I had 30 external behavior trees to instantiate, I would have to spend a lot of time dragging all the nodes until I find the one I want to debug.
Is there a way to make the editor place the nodes in the correct order and in a way that they are all visible without having to shuffle manually?
I know the order under a Parallel node matters little but I have another tree with a selector and yet another one with a sequence so for those two, this would be a big issue if the order wasn't respected. Not to mention that some of these sub-trees could have a conditional abort in them so priorities are important.
My third question is more general: is this a good idea to design my trees this way? I like the idea of having a big manager (each one of my three "Behavior Tree" components) which does very little and describes no decision making at design-time, they're only there to manage, and a group of "worker" external behavior trees that may or may not be needed depending on the situation (once again, this is when the level starts, I shouldn't need to replace an already instantiated external behavior tree later).
Thanks!
In my game, characters are all identical at design-time (they all come from the same prefab) but have several ScriptableObjects that define their identities when the game starts. For example, one character may be a thief, another may be a named character, a third one may be a guard etc. I want them all to have different behaviors that depend on their identities but also on the current level because the current level tells a story involving the player and different levels mean different stories to tell. One behavior for a character in a level might become irrelevant for the same character in the next level so not all are reusable and that's okay.
For example, a named character may need to come to the player to initiate a conversation, and depending on the outcome of that conversation may give a quest or not. This would be handled by an external Behavior Tree that would be useful only for this level and this character.
To do this, my idea would be to have a very simple high-level skeleton Behavior Tree running a Parallel node under a Repeater, and under that Parallel node a single Behavior Tree Reference which list of external Behaviors would be calculated once when the level starts. I could also have three BT components instead of one. One of them would run the tasks in parallel, another in sequence and another with a selector. I'm not entirely decided on that yet.
So I have a few questions about this approach.
Here is what that simple skeleton tree looks like at design-time:
Don't pay too much attention to the names of the external behavior trees; What's in them, what they do and how they do it is not relevant to this post.
The list of External Behaviors in the Behavior Tree Reference is currently filled by hand but I want to fill it automatically from data gathered from different sources, before the Behavior Tree Reference is consumed and replaced by the instantiated External Behavior Trees. How can I reference the Behavior Tree Reference in my code and fill its list before it instantiates the trees in said list?
My second question would be about what happens next. When the Behavior Tree Reference is replaced by instances of its contents, the resulting sub-trees all overlap each other (except the first one), like this:
But what I want it to look like is this:
(I know the order of the nodes does not match the list displayed in the first screenshot, this is just for the sake of example. I just dragged the five nodes manually.)
Not only the order in which the nodes are placed under their parent is supposed to be important, but debugging this would be too cumbersome because if I had 30 external behavior trees to instantiate, I would have to spend a lot of time dragging all the nodes until I find the one I want to debug.
Is there a way to make the editor place the nodes in the correct order and in a way that they are all visible without having to shuffle manually?
I know the order under a Parallel node matters little but I have another tree with a selector and yet another one with a sequence so for those two, this would be a big issue if the order wasn't respected. Not to mention that some of these sub-trees could have a conditional abort in them so priorities are important.
My third question is more general: is this a good idea to design my trees this way? I like the idea of having a big manager (each one of my three "Behavior Tree" components) which does very little and describes no decision making at design-time, they're only there to manage, and a group of "worker" external behavior trees that may or may not be needed depending on the situation (once again, this is when the level starts, I shouldn't need to replace an already instantiated external behavior tree later).
Thanks!