|
template<class T > |
using | aitoolkit::bt::node_ptr = std::unique_ptr<node<T>> |
| Heap-allocated pointer to node.
|
|
|
template<typename T , node_trait< T > ... Children> |
std::vector< node_ptr< T > > | aitoolkit::bt::node_list (Children &&... children) |
| Helper function to create a list of nodes.
|
|
Introduction
A behavior tree is a tree structure where each node represents a behavior. The tree is evaluated from the root node to the leaf nodes. The leaf nodes are either tasks or checks. A task is a node that performs an action and returns either success or failure. A check is a node that returns either success or failure based on some condition.
flowchart TD
root{{Selector}} --> seq1
root --> seq2
root --> seq3
seq1{{Sequence}} --> seq1a1
seq1 --> seq1a2
seq2{{Sequence}} --> seq2a1
seq2 --> seq2a2
seq3{{Sequence}} --> seq3a1
seq3 --> seq3a2
seq1a1[Check enemy in attack range]
seq1a2[[Destroy enemy]]
seq2a1[Check enemy in sight]
seq2a2[[Move towards enemy]]
seq3a1[[Move towards waypoint]]
seq3a2[[Select next waypoint]]
style root fill:darkred
style seq1 fill:darkgreen
style seq2 fill:darkgreen
style seq3 fill:darkgreen
Usage
First, include the header file:
#include <aitoolkit/behtree.hpp>
Then, create a blackboard class that will hold the state of the tree:
struct blackboard_type {
glm::vec2 agent_position;
glm::vec2 enemy_position;
float attack_range;
float sight_range;
size_t current_waypoint;
std::vector<glm::vec2> waypoints;
};
Next, create the tree:
using namespace aitoolkit::bt;
node_list<blackboard_type>(
node_list<blackboard_type>(
auto distance = glm::distance(bb.agent_position, bb.enemy_position);
return distance <= bb.attack_range;
}),
return execution_state::success;
})
)
),
node_list<blackboard_type>(
auto distance = glm::distance(bb.agent_position, bb.enemy_position);
return distance <= bb.sight_range;
}),
return execution_state::success;
})
)
),
return execution_state::success;
}),
return execution_state::success;
})
})
)
);
Finally, evaluate the tree:
auto bb = blackboard_type{
.agent_position = { 0.0f, 0.0f },
.enemy_position = { 1.0f, 1.0f },
.attack_range = 0.5f,
.sight_range = 1.0f
};
while (true) {
auto state = tree.evaluate(bb);
if (state == execution_state::success) {
break;
}
}
◆ execution_state
Represent the state of a node.
Enumerator |
---|
success | The node was successful
|
failure | The node failed
|
running | The node is still running
|