Behavior
Important methods
Start
This method is invoked once the Behavior is assigned to entity. Its implementation is not required.
Finish
This method is invoked once IsFinished
method returns true
, before the next behavior is chosen.
Its implementation is not required. Your implementation may behave differently depending on behavior status.
IsFinished
This method returns true
if the behavior should terminate.
Its implementation is not required. The default implementation returns true.
IsLegal
This method indicates whether it’s possible to execute the behavior and if it should be considered by decision making algorithms. If a behavior turns illegal during its execution, it will be automatically finished with DELEGALIZED status.
Its implementation is not required. The default implementation returns true.
IsInterruptible
This method indicates whether it’s possible to interrupt behavior execution. If it is Reasoner may decide to finish behavior immediately with SUSPENDED status.
Its implementation is not required. The default implementation returns true.
Behavior Status
-
ACTIVE - behavior is currently assigned to entity
-
SUSPENDED - behavior was assigned to entity but its execution was interrupted
-
FINISHED - behavior finished properly
-
DELEGALIZED - behavior is no longer legal
Simple behavior implementation
An exemplar implementation of a simple behavior looks like this:
-
C++
-
C#
class GoTo : public grail::Behavior
{
private:
Location target;
Unit* controlledUnit;
public:
GoTo(const Location& target)
: target{target}
{
}
void Start(grail::AIEntity& owner) override
{
controlledUnit = owner.GetBlackboard().GetValue<Unit*>("controlled_unit");
if (controlledUnit->GetCurrentLocation() != target)
{
controlledUnit->GetMovement().GoTo(target);
}
}
void Update(grail::AIEntity& owner, float deltaTime) override
{
//Place any time-dependent or durable logic in behavior's update
}
void Finish(grail::AIEntity& owner, grail::BehaviorStatus status) override
{
controlledUnit->ReportMovementFinished();
//We may also place any cleanup logic in this method
}
bool IsFinished(const grail::AIEntity& owner) const override
{
return controlledUnit->Location == target;
}
bool IsLegal(const grail::AIEntity& owner) const override
{
//if IsLegal returns false, the behavior will be omitted by decision-making algorithms or interrupted
return true;
}
}
public class GoTo : Grail.Behavior
{
private Location target;
private Unit controlledUnit;
public GoTo(Location target)
{
this.target = target;
}
public override void Start(AIControlledEntity owner)
{
controlledUnit = owner.Blackboard.GetValue<Unit>("controlled_unit");
if (controlledUnit.CurrentLocation != target)
{
currentUnit.Movement.GoTo(target);
}
}
public override void Update(AIControlledEntity owner, float deltaTime)
{
//Place any time-dependent or durable logic in behavior's update
}
public override void Finish(AIControlledEntity owner)
{
controlledUnit.ReportMovementFinished();
//We may also place any cleanup logic in this method
}
public override bool IsFinished(AIControlledEntity owner)
{
return controlledUnit.Location == target;
}
public override bool IsLegal(AIControlledEntity owner)
{
//if IsLegal returns false, the behavior will be omitted by decision-making algorithms
return true;
}
}