Download

Behavior Tree Tutorial

Great work Daniel, I’m finally starting to understand this.
Mike did a good job in highlighting this, but I didn’t understand anything he said in his original post and was going to put up a comment asking for some clarification on most of what he wrote :slight_smile:

Sorry about that. I’ll update this within the week once I incorporate the changes Daniel suggested.

There wasn’t any documentation when I first got the Behavior Tree working in my project, so it was guess work and experimentation on my part. I also tried to tell what a Behavior Tree was in a generic sense, maybe I should remove that and keep it just to how they work in UE4.

No, don’t apologise Mike, it’s not your fault that I’m a bit thick ;). I think that what it is, you’re from a programming background I presume and so it’s hard to translate your knowledge over to someone who has no concept of programming whatsoever :smiley:
Just by creating this thread, you got me really intrigued and so I’m watching it daily. Great work for at least bringing it out in the open …

Glad this is all helping. :slight_smile: Mike, thanks for helping out in the community here… it’s impressive what you did even without any docs at all from us. :slight_smile:

Quick heads-up for another relevant thread: UE4 Pathfinding basic AI

Lukasz Furman gives an example of a Blueprint Task for choosing where to path (since I only gave an example of a Blueprint Decorator).

@Daniel

Can you show how to make a service that sets or gets a condition that requires some computation like looping through actors, and then the decorator that goes with it to actually check on it, in blueprint only?

I have redone my BT to be Blueprint Only, and have it working in a basic form. But I think I am doing some things wrong still and would like some more clarification, such as:

How do you return, in progress from a BTTask_Blueprint? I only see how to return success or failure.

What is the best way to do a condition check in blueprints that requires some computation? Does the service go hand in hand with a decorator condition, or am I misunderstanding.

Lastly, I did put these up on AnswerHub, but they’ve been pushed back and there’s been a lot of response on this thread. I put a Bug on AnserHub regarding this. If you use BP node SpawnAI, the resulting pawn with the BT, always has the controller AIController, instead of the one specified in the pawn. That is, if the AIController is also a blueprint, I see how in ShooterGame casting to the correct controller is done in the BT, but that is a C++ AIController. Possibly, the BP created one isn’t getting registered correctly or something.

Just a guess, but can’t cast to a custom AIController in BP’s. Which is where I put a function that got the closet mouse, setting it’s location and a bool for if it existed on the AIController, that I intended to call the set function from the Service setting the Blackboard Key, and then test from the decorator condition.

But, casting always fails so I couldn’t test if the rest of it worked. Is that on the right track, or is it wrong, the casting aside?

This has been already fixed in CL#1975683, which was pretty long time ago (mid January), so maybe it’s time for an update? :wink: We work on AI stuff heavily all the time, laging behind with old code is not a good idea :smiley:

The bug needs to be reopened then. I’m in a blueprint only project off the public build. 4.0.2.

Re: Your AIController casting issue, I answered your question on AnswerHub: Why doesn't BP Spawn Node set correct AI Controller subclass? - UE4 AnswerHub

(It does appear that the SpawnAI node fails to create the correct AIController class; I’m testing a fix for that now, but you can use SpawnActor + some other functions instead for now; see my answer above.)

BTTask_Blueprints don’t return “in progress”… if you don’t return anything at all, that means it’s “in progress”. You can then either use tick or some other event to determine when you’re finished (with success or failure).

FYI, I’ve been working heavily on the forthcoming behavior tree documentation for the past few days. I’ll make sure to spend some time answering forum and AnswerHub questions each day, but I’m trying to focus more on getting the real documentation done in the hopes that it will answer most questions.

Thanks Daniel, your awesome!

No problem on the time for questions. I figured the Epic Devs needed time to develop and such and compress when they answered the stuff. It looks like it takes tons of time. The feedback that you guys are giving the community is amazing. I’m not sure any software company has ever given this level of communication to the user group.

Fantastic :cool:, you’re the main man Daniel :wink:

And mike, I agree totally, Epic have been unprecedented in their help on these forums :slight_smile:
I’ve managed to solve 99% of my missing workflow in less than 3 weeks, unlike UDK that took me the best part of 3 years and then 3 more building :smiley:

@Mikepurvis

Here is an example of how you would set up a service that does some calculations then check the result from a decorator. Create a service by right clicking in the Content Browser then create a blueprint of type BTService_BlueprintBase under Custom Classes. Here is the outline for the service event graph:

This service is setting a bool specified by the key “Your Blackboard Key to Set” in the blackboard . You will need to add a similar variable of type BlackboardKeySelector to your service as follows:

Make sure that this variable is set to “editable” then it will show up in the details view of the service when you add it to a composite node in a behavior tree. The following example is using the Shooter Game tree and blackboard with the key selector set to the “Needs Ammo” bool blackboard key. The type of the key that you select should match the type that you are setting the value as in the service event graph. This is also where you can set how often this service ticks and does your calculations. In the this case the service will get its Event Receive Tick every 0.5 seconds:

Finally, you can add a Blackboard decorator to the tree that checks this value. This decorator can make use of the observer aborts property that Daniel explained earlier in this thread to change the tree execution flow in response to that blackboard value being set from your service:

This example used a key of type bool, but you could have this use any of the other blackboard types. Your service could use a key similar to the Enemy key in Shooter Game which is an Object of type ShooterCharacter. From your earlier post, if you have an object class for a “Mouse” you could have a blackboard object key for “TargetMouse” that holds an object of type Mouse. Then your service could use SetBlackboardValueAsObject to set the TargetMouse when it finds a nearby mouse.

@Stephan

Thanks, that’s really clear.

I’m having a strange thing happen. I don’t know if it is how I’m setting it up or if it’s a bug.

I have a service on a composite node. If it’s directly under the root it fires as expected. But, if it’s parent is a composite node it never fires.

Edit: I’m not sure why I was having that problem, but deleting it and starting over, it works now.
fdbc5940c554f56f4613c741498a477eb5a33841.jpeg

It’s kind of hard to tell, since attached imaged is very small, but I guess it could be related to way services work.

Behavior tree operates on tasks. Think about it as constant loop: task finished > search for next task > task found > update auxiliary nodes (services, observing decorators, parallels, etc) > execute task.

It basically means, that you can’t rely on data provided by service to control any decorators in underlying branch. On positive side, this approach is better for performance, as we don’t trigger any updates when going through tree during task search. I’d even say it’s safer from gameplay point of view, because you don’t have to worry about modifying game state by unnecessary updates when branch is just entered and left during search.

However, root level services are different. Since by default tree execution is looped, root level services are started together with tree and stopped only when tree instance leaves stack (e.g. subtrees). It makes them ideal for any modifiers that are always enabled for given tree (either ticking, or just updating some properties on enter/leave notifies).

That’s why your solution worked on root level. If you need to move service down the tree, you have to reorganize structure as well. For example: add some failsafe wait task as last child, and make decorators abort lower priority execution?

Hey Daniel!

Thank you for helping out on this thread. It has been a huge help. I’m still a bit confused. When trying to replicate the shooter game example project in my own project, I found that I couldn’t build the Search for an Enemy BT Service because my libraries couldn’t find the ‘Find Closest Enemy’ function. I also don’t seem to have the behavior library when I look for it in the function search.

Untitled.jpg

Sorry if this is something obvious but I’m confused. :frowning:

Thanks for the help.

FindClosestEnemy is member function of AShooterAIController exposed to blueprints. It can’t exist on engine level, since concept of “enemy” and how it should be picked depends on game design.

You can use blueprint function GetAllActorsOfClass to obtain all actors of interest and iterate through them to select best one.

Hi Mike,

thanks for this awesome stuff. I actually saw the video before I purchased the Unreal Engine because I looked up Behaviour Trees on youtube. Had to show it to my wife immediately because it was so well made :-). Would you mind sharing the full source? I don’t for instance see how you turn the cat to look at the cursor. Can you elaborate on that?

Thanks
Markus

If you look in mike’s signature, he’s making a commercial game out of the kitty project, (and it sounds awesome) so I doubt he’ll be uploading any source code or files yet :slight_smile:

Thanks Lukasz!

That makes sense. Are there any examples of exposed combat BPs? We’ve got the enemies moving towards the player, but looking to get the enemies attacking now! :slight_smile: