Just writing my first behaviour tree, and had some quick questions on general behaviour and flow control, if ok to ask:
If multiple characters have the same AI and behaviour tree, does each character have their own instance of the black board (e.g. if I set a target object key in the BB, it will only be for the character for whom it was set)?
Are decorators only checked on entry to the composite that contains them, or are they constantly checked while any following task (in the same composite) is still running (e.g. before each tick event)?
Does a service that constantly runs still get triggered for a character, even if that character is looping in a task further down the tree (e.g. a character state check service at the top of the tree, even if a character AIMoveTo node is still running further down the tree and waiting to finish execute)?
What is the effect of the decorator detail “Flow Control > Observer Aborts” (None, Self, Lower Priority, Both)?
Is it possible to use a simple decorator (that doesn’t require a user defined one) that can simply check if a variable in the character blueprint is equal to a specific value, or even to check if a BB key is set to a specific value (e.g. if you just want the decorator to make a simple check to see if the character is in a specific mode [bool/int/enum])? I’m guessing I can create and set a BB key for each decorator condition I want in the BT, then use “Compare BB Entries” to compare the pre-set and dynamic value, but would just ease my OCD…
Wow, this is a fairly complex set of questions. I’ll try to help answer the ones that I know.
- Yes, each instanced character will have their own blackboard values. You should note, that you can also set a blackboard value to be synced between all instances by checking the “instance synced” checkbox in the blackboard details window.
- The decorator should only be run when it receives an execute, and to my knowledge won’t run on tick, even if a task beneath it is still running. However, if you set observer aborts, then it will be checked every tick.
- A service will receive a tick each time it is executed in the AI tree, but it will also receive a tick during execution of a task further down the tree every period of time based on the “interval” value set in the details panel. So if you set the interval to 5, the service will run every 5 seconds even if a MoveTo node is still executing beneath it.
- Observer Aborts has something to do with a change in the BTD condition cancelling execution of tasks. This way, you could cancel a Move To if your AI state changes. I’m not 100% sure exactly how it behaves, but you can check out a good explanation here observer aborts explained
- I don’t know if there’s a built in decorator for checking variables in the character blueprint, but to check a value in the BB, just add the standard blackboard decorator. You can then set the key you want to check, and the value for that key you want to check against. Hopefully that’s what you were looking for.
Hi, Thanks for your answers. Could I ask 2 more questions if it’s ok?
- How do I get a reference to the character the BT is running for? I have an example (please see below) that gets the owner actor from the event tick, casts it to generic controller, then “Gets Controlled Pawn”, but the return value from Get Controlled Pawn always returns none (my owner actor is my Ai controller derived directly from AIController).
- If I understand correctly, a character references the AI controller it wants to use in “Details > Pawn > AI Controller”. Does this create a separate instance of the AI controller for each character (including it’s variables)? (Which in turn then declares the blackboard to use and then runs the behaviour tree). If this is the case, it kind of turns the way I saw things upside-down, as at the moment I was going to create/spawn an instance of the AI controller from an owning object (e.g. player controller/AI decision making object), then thought each character would then register with it…!
Sorry for the extra question…
- You shouldn’t be casting to Controller, as that will cast to a player controller, rather than an Ai controller. I’ve attached a picture showing two common setups.
- Yes, each Ai must have it’s own controller. The Ai controller, the behavior tree, the blackboard, and everything related to them are instanced when you create a new Ai character. This really makes sense when you think about it. How would your Ai behave as individuals if they all shared the same Ai tree and controller? Also, it should be noted that when you spawn your Ai in blueprints, you also have to spawn the default controller, or your Ai simply does nothing.
There are some good in depth tutorials on the Ai controller on youtube that’ll step you through the process of building some cool stuff if you’re interested in learning more.
Also, would you mind marking my answer as correct if it’s helped you solve your question?
Thanks for your answer again. I ticked your last post as answered (sorry my first post), I’m not sure if I should have set my second one as a new thread?
I tried as shown in your last post (really thought it would have been the answer), where I replaced the Cast to Controller with Cast to AIController, but the Get Controlled Pawn still returns None. Sorry for asking again, but I really want to get this working.
So the flow is: I have a HUD widget that when I press the recruit button, tells the player controller that I want a new character (works). The player controller then spawns a new character and calls the new characters init function, the init function sets some character variables then spawns its AI Controller (MyUnitController, parent AIController) that is the same class as defined in its “Details > AI Controller” (works - the character and its controller are spawned). The MyUnitController then runs its behaviour tree, with the first service straight after root being the same as shown in your image above, with breakpoints placed straight after event tick and on the cast to character node. As soon as I press the recruit character button, the code breaks at the service breakpoint, but when I step to the cast to character node, the return from GetControlledPawn is still none.
I also tried calling GetControlledPawn (and GetOwner) straight from the MyUnitController, from a “self” reference (thought if it worked could pass the character reference to the blackboard), but still returned none.
“…when you spawn your Ai in blueprints, you also have to spawn the default controller…”
Just checking I understand this. I spawned the new character from the player controller, then in the characters initialisation function/event begin play, I explicitly spawned the AI controller (the same type as defined in it’s “Details > AI Controller”), is this what you meant?
I think asking in a comment for further clarification is fine. I haven’t been posting for very long on the forums either.
So it sounds like an interesting setup you have. I haven’t tried spawning the Ai controller from inside the Ai character itself. Your Ai controller may not be successfully possessing your pawn. I’ve attached a picture with the basic setup that I’ve been using to spawn my Ai. You might try spawning the Ai from within the player controller using the method attached, and then see if you can access the controlled pawn.
Hi Zapheroc, Thanks for the answer, that was it, I needed to use the “Spawn Default Controller” node (I was using “Spawn Actor [MyAiControllerType]” instead), all works now, thanks…