In the GOAP system, an action represents a discrete step an agent can undertake to achieve a specific goal. Actions are defined by their requirements and effects, which guide the chaining of actions to form a plan.
Components of an Action
Actions are composed of three primary parts:
Config: Configuration settings for the action.
Action Class: The logic and behavior of the action.
Action Data: Temporary data storage for the action's state.
Action Config
The configuration provides essential settings for the action, enabling its integration into the GOAP graph.
Conditions
Conditions are a set of world states that must be met for the action to be executable. Each condition references a WorldKey and specifies whether its value should be true or false.
Effects
Effects describe the changes in world states that result from performing the action. Each effect references a WorldKey and indicates the expected outcome (true or false).
BaseCost
This represents the inherent cost of executing the action, excluding any additional costs (like distance) that the planner might add.
Target
Every action has an associated target position. Before executing the action, the agent will move towards this target, depending on the MoveMode. Targets are identified using TargetKey, such as ClosestApple or ClosestEnemy.
InRange
This value specifies the proximity required between the agent and the target position before the action can commence.
MoveMode
MoveMode determines how the action and movement are coordinated:
MoveBeforePerforming: The agent moves to the target position before initiating the action.
PerformWhileMoving: The agent concurrently moves to the target and executes the action.
Action Data
Action data provides temporary storage for the action's state for an individual agent. This data is not shared across agents or across multiple invocations of the same action.
Action Data Injection
To reference other classes on the agent, use the GetComponent attribute. This provides a cached component instance, optimizing performance by avoiding frequent GetComponent calls.
The action class defines the behavior of the action. It should be stateless since a single instance might be used to execute the same action on different agents. The class inherits from ActionBase<TData>, where TData is the action data class.
ActionRunState
This enum indicates the action's current state:
Continue: The action will persist and be re-evaluated in the next frame.
Stop: The action will terminate, and control will revert to the planner.
Examples
The provided examples illustrate how to implement specific functionalities within the action class and action data. They've been retained in their original form for clarity.
Examples
WanderAction.cs
usingCrashKonijn.Goap.Behaviours;usingCrashKonijn.Goap.Enums;usingCrashKonijn.Goap.Interfaces;usingUnityEngine;namespaceDemos.Actions{publicclassWanderAction:ActionBase<WanderAction.Data> { // You can implement a custom cost function. This is useful if you want to add dynamic costs to the action.publicoverridefloatGetCost(IMonoAgent agent,IComponentReference references) {return5f; } // This method is called to determine if the agent is in range for the action. It is called every frame while the action is running.
// This could be used to perform a physics check to actually guarantee line of sight for example. public virtual bool IsInRange(IMonoAgent agent, float distance, IActionData data, IComponentReference references)
{ return distance <=this.config.InRange; } // This methods is called when the action is created. It is used to initialize the action.publicoverride void Created() { } // This method is called when the action is started. It is used to initialize the action.publicoverridevoidStart(IMonoAgent agent,Data data) { } // This method is called every frame while the action is running. It is used to perform the action.publicoverrideActionRunStateOnPerform(IMonoAgent agent,Data data,ActionContext context) {returnActionRunState.Stop; } // This method is called when the action is stopped. It is used to clean up the action.publicoverridevoidEnd(IMonoAgent agent,Data data) { } // Action data class. It stores the state of the action for a single agent. This data is not persistent between agents or between multiple runs of the same action.
publicclassData:IActionData { // The target position of the action. This is set by the planner.publicITarget Target { get; set; } } }}