Description of the behavior system.
The behaviors are a center part of Recast/Detour, they will allow you to move the agents in a specific way.
Some predefined behaviors are provided, but of course the user has the possibility to create his own.
Basically the goal of a behavior is to compute a new velocity for a given agent. This new velocity will be used to update the position / orientation of the agent.
It is important to make difference between the following two properties of an agent:
When updating the position of an agent, the desired velocity is used to compute the current velocity which is itself used to determine the next position. In other words, the user should not update the current velocity of an agent himself (although it can be done).
Just remember that the current velocity is updated according to the desired velocity.
Several interfaces are provided for behavior creation. The user must inherit from one of these.
Normal behavior: dtBehavior
This is the highest interface in the behavior hierarchy. When implementing this interface, the user has to implement the
dtBehavior::update() method, which defines how the behavior will affect the data of the given agent.
Steering behavior: dtSteeringBehavior
A steering behavior is a special kind of behavior. A steering behavior works by computing a force that should be applied to the current velocity of an agent in order to get the desired velocity. This is why the user should doesn't need to implement the
dtSteeringBehavior::update() method, but instead he needs to define the
dtSteeringBehavior::computeForce() method (and maybe the
dtSteeringBehavior::applyForce() method as well).
A steering behavior can be parametrized (see below).
Parametrized behavior: dtParametrizedBehavior
Most of the behaviors cannot work on their own, they need parameters. And these parameters can vary from agent to agent (for instance with a following behavior, each agent can follow a different target). In order to allow your behavior to be parametrized, you need to inherit from
dtParametrizedBehavior (which implement the
dtBehavior interface) and define the
dtParametrizedBehavior::doUpdate() method. This will give you access to a set a methods allowing you to store and access your parameters (which can be represented by any data structure) for every agent.
Recast/Detour provides you with a set of predefined behaviors:
dtAlignmentBehavior: The agent moves in the same direction as its targets.
dtCohesionBehavior: The agent moves towards the center of gravity of its targets.
dtFlockingBehavior: Agents move like a flock, or a herd. This basically means that they will try to stick together as they move, heading in the same direction, and without bumping into each other.
dtArriveBehavior: The agent moves toward the specified position.
dtPathFollowing: Computes and follows a path from the agent to the specified position using the navigation mesh. This path can be dynamically updated.
dtPipelineBehavior: This behavior acts like a container for other behaviors. The agent will be updated with every behavior contained in the pipeline. This is useful for instance if you want to combine a dtPathFollowing and a dtCollisionAvoidance behavior.
dtSeekBehavior: The agent tries to "catch" its target (another agent). Position prediction can be done for a more efficient path.
dtSeparationBehavior: The agent moves away from the center of gravity of its targets.
Most of these behaviors need some parameters (distance, targets, etc.), and those parameters must be related to the agents. For each behavior there is a data structure containing the necessary parameters. This structure is called
BehaviorName must be replaced by the name of the behavior). Once the parameters are defined, you need to associate them with an agent, then the behavior will know what parameters must be used according to the agent it is updating. Here is a sample code:
At some point you might want to create your own behaviors. This can easily be done by using the provided interfaces listed above.
Let's take an example. Say we want to create a behavior where an agent would always take the opposite velocity of its target.
First of all, since we are going to need some parameters (for the target), let's create them:
Now we can create our behavior. Since it uses parameters, we need to inherit from
Now we have a (simple) behavior ready to be used.
Now our behavior has been assigned to the agent. The next time the crowd updates its agents, the agent will go in the opposite direction of its target.
|Parameters for the alignment behavior. More...|
|Defines the alignment behavior. More...|
|Interface defining a behavior. More...|
|Parameters for the alignment behavior. More...|
|Defines the cohesion behavior. More...|
|Parameters for the collision avoidance behavior. More...|
|Defines a behavior for collision avoidance. More...|
|Parameters for the flocking behavior. More...|
|Flocking behavior. More...|
|Parameters for the Arrive behavior. More...|
|Defines the GoTo behavior. More...|
|Empty data structure used when no parameters are required. More...|
|class||dtParametrizedBehavior< T >|
|A behavior that can be parametrized. More...|
|Represents a dynamic polygon corridor used to plan agent movement. More...|
|Parameters for the path following behavior The parameters will be automatically initialized when used for the first time by the PathFollowing behavior. More...|
|Defines a behavior for pathfollowing. More...|
|Behavior having the ability to contain other behaviors. More...|
|Parameters for the seek behavior. More...|
|This class implements the seek behavior. More...|
|Parameters for the separation behavior. More...|
|Implementation of the separation behavior. More...|
|class||dtSteeringBehavior< T >|
|Interface defining a steering behavior. More...|