Design for units collecting wood

I’m trying to come up with a design which would play well with the Unreal engine, in this case for units who need to find trees to collect wood

A Unit is a Character with an AIController and BehaviourTree

This Behaviour tree has a custom C++ task for finding the closest tree

But to do this, this task would need all the available forests on the map, and it would be expensive to find these everytime. I figured it therefore makes sense for the task to draw from some ResourceManager class, which keeps knowledge of all the active forests.

By this point ResourceManager would be a singleton, but I’m not sure how my BT task would get that from somewhere global like the GameMode?

I haven’t found any need to make a component yet, I’m not sure if this problem calls for one.

No need to find them every time. If forest is a smart object, and it should be, as soon as it’s spawned, make sure to add it to some list that you will keep in Game Mode (for single player), or GameState (for multiplayer). When you have location coordinates in the list, you can calculate which one is closest one, and send AI’s to chop wood.

This will be optimized, as you don’t have to use GetAllActorsOfClass at all. Calculating distance between vectors is kinda cheap, and you should be good.

Thank you - and how would my BT task access this list of forests on the Game Mode?

it wouldn’t have a reference to Game Mode, so is there some special way to access the Game Mode from anywhere?

To access Game Mode from anywhere, use this in C++

AYourGameMode* GameMode = GetWorld()->GetAuthGameMode<AYourGameMode>();

This casts it to your game mode, and then if your list is public variable, you can get the forest. There are downsides to making it public, so you might want to encapsulate it. Or even better, let the game mode decide (calculate) which one is the closest one, and then your task can just call YourGameMode->GetClosestForest(myLocation), and you should be good to go.

For BP, you have a node GetGameMode, and then just cast it to your GameMode. Even easier :slight_smile:
Just make sure your list is BlueprintReadOnly

Great, thank you!

1 Like