Skip to content

GOAPAgent

The GoapAgent component is the core AI driver. It owns the planner, executor, and blackboard, and coordinates the entire GOAP pipeline every frame.


Required Components

Adding GoapAgent to a GameObject automatically adds the other required components via [RequireComponent]:

Component Added By Purpose
GoapAgent You Core AI driver — owns the planner, executor, and blackboard
GoapAgentContext Auto Per-agent overrides, capability cache, and key registration
SensorController Auto Initializes and polls sensors defined in the Brain

Optional Components

Component When to Add
GoapRecollectionSystem When the Brain uses temporal memory (Brain.UsesSpatialMemory = true). Provides confidence-decay AI memory.
WayPointManager When the agent needs patrol waypoints. Pairs with WaypointSensorSO.

Inspector Settings

Field Type Default Description Notes
Brain GoapBrainSO The Brain asset that defines this agent's AI Required. Agent does nothing without a brain.
Enable Goal Preemption bool true Allow higher-priority goals to interrupt mid-plan Disable for agents that should always finish their current plan.
Goal Reevaluation Interval float 0.5s How often to check for a better goal during execution Range: 0.1–2.0s. Lower = more responsive, slightly more CPU.
Goal Preemption Margin float 0.1 Hysteresis margin to prevent goal thrashing Range: 0–1. A value of 0.1 means a new goal must have 10% higher priority to preempt the current one. Increase if goals are oscillating.
Transition Check Interval float 0.1s How often FSM transitions are evaluated Range: 0.05–0.5s. Keep low for responsive state switching. Cost is minimal (just belief evaluation).
Max Consecutive Failures int 5 Planning failures before the agent enters fallback behavior Increase for complex brains where initial planning attempts may legitimately fail.
Override Start State GoapBehavioralState Override the Brain's default initial state Useful for spawning agents in a specific state (e.g., already alerted).
Debug Plan Search bool false Log planner A* search steps to the Console Disable in production. See Performance Tuning.

Public API

Properties

Context

public IGoapAgentContext Context { get; }

The agent's context — provides access to the blackboard, cached capabilities, and per-agent overrides.

Blackboard

public GoapBlackboard Blackboard { get; }

Direct access to the agent's blackboard. Use this to read or write world-state values from external scripts.

// Check if an agent can see its target
var agent = GetComponent<GoapAgent>();
bool canSee = agent.Blackboard.GetBool(canSeeTargetKey, false);

CurrentState

public GoapBehavioralState CurrentState { get; }

The agent's current behavioral state (e.g., Patrol, Combat). Use for UI display or conditional logic.

// Display the agent's current state in a debug UI
debugText.text = $"State: {agent.CurrentState.Name}";

CurrentAction

public GoapActionInstance CurrentAction { get; }

The action currently being executed, or null if no plan is active.

CurrentGoalInstance

public GoapGoalInstance CurrentGoalInstance { get; }

The goal the planner is working toward. Useful for debugging or building UI that shows agent intent.

ActivePlan

public List<GoapActionInstance> ActivePlan { get; }

The current action sequence. null or empty if no plan exists.

// Log the full plan for debugging
if (agent.ActivePlan != null)
{
    foreach (var action in agent.ActivePlan)
        Debug.Log($"  → {action.Name}");
}

Brain

public GoapBrainSO Brain { get; set; }

The brain asset. Can be swapped at runtime to completely change an agent's AI configuration.

// Swap brain when an agent becomes a boss variant
agent.Brain = bossBrain;

Warning

Swapping the brain at runtime reinitializes the agent's state machine, sensors, and planner. Ensure the new brain's key manifest is compatible.


Methods

ForceReplan()

public void ForceReplan();

Clears the plan cache and requests a new plan on the next tick. Use this when external events invalidate the current plan (e.g., a target teleports, a door locks) and the change bypasses the normal sensor/belief pipeline.

// Force replan when the player uses a teleport ability
public void OnPlayerTeleported(Vector3 newPosition)
{
    agent.Blackboard.SetVector3(targetPositionKey, newPosition, "Teleport");
    agent.ForceReplan();
}

Tip

Prefer letting the planner detect changes via belief updates. Only use ForceReplan() when the change bypasses the normal sensor/belief pipeline. The ContentRevision gate already avoids redundant replanning.

SetBehavioralState(GoapBehavioralState newState)

public void SetBehavioralState(GoapBehavioralState newState);

Force a manual FSM state transition. Interrupts the current plan and enters the new state. Use for scripted events (cutscenes, spawn states).

// Force agent into combat state when an alarm triggers
agent.SetBehavioralState(combatState);

Note

In most cases, let belief-driven FSM transitions handle state switching. Manual transitions are for external game events that override normal AI behavior.

UpdateAi(float deltaTime)

public void UpdateAi(float deltaTime);

Manually tick the AI pipeline. Only needed if you've disabled the agent's MonoBehaviour update and are driving AI from a custom manager (e.g., for batched updates across many agents).

SetContext(IGoapAgentContext context)

public void SetContext(IGoapAgentContext context);

Switch the agent's context at runtime. Use when sharing a brain across agents with different capability setups.


Events

OnPlanUpdated

public event Action OnPlanUpdated;

Fires when a new plan is produced. Use for UI updates, audio cues, or debug logging.

agent.OnPlanUpdated += () =>
{
    Debug.Log($"[{agent.name}] New plan: {agent.ActivePlan?.Count ?? 0} actions");
};

GoapBrainSO

The Brain is the top-level configuration asset. It contains everything the agent needs:

// Configuration
public SerializableGuid DefaultStateId;       // Which state to start in
public bool UsesSpatialMemory = false;         // Enable RecollectionSystem
public int MaxPlannerIterations = 2000;        // A* search cap

// Collections
public List<GoapBehavioralState> States;       // All behavioral states
public List<GoapSensorSO> Sensors;             // Sensors attached to this brain
public List<GoapStateTransition> Transitions;  // FSM transitions between states
public List<GoapKey> Keys;                     // Blackboard key definitions
public List<BrainKeyMapping> KeyManifest;      // Slot → Key wiring

Runtime Lookups

public GoapBehavioralState GetStateById(SerializableGuid stateId);
public GoapBehavioralState GetDefaultState();
public GoapActionInstance GetActionById(SerializableGuid instanceId);
public GoapGoalInstance GetGoalById(SerializableGuid instanceId);
public GoapKey GetKeyById(SerializableGuid keyId);

GoapBehavioralState

Each state defines its own scope for planning:

public string Name;                            // Display name (e.g., "Patrol", "Combat")
public SerializableGuid StateId;               // Unique identifier
public List<GoapActionInstance> Actions;        // Actions available in this state
public List<GoapGoalInstance> Goals;            // Goals the planner can pursue
public List<GoapBeliefInstance> Beliefs;        // Beliefs used by actions and goals

The planner only considers actions and goals within the current state, keeping the A* search space focused.


GoapStateTransition

Transitions switch between behavioral states based on belief conditions:

public SerializableGuid TransitionId;          // Unique identifier
public SerializableGuid SourceStateId;         // State this transition fires from
public SerializableGuid TargetStateId;         // State to transition to
public GoapBeliefInstance Condition;           // Belief to evaluate (null = unconditional)
public bool TargetValue = true;                // Required belief result to fire

Note

There are two transition systems: belief-driven FSM transitions (checked on a timer, fire as interrupts) and goal-driven transitions (GoapGoalInstance.TransitionToStateId, fire once after plan completion). See The Planning Loop for details.


Custom Agent Context

The default GoapAgentContext pre-caches NavMeshAgent, Animator, and AudioSource. If your agent needs additional components cached for O(1) access, extend the context:

public class MyAgentContext : GoapAgentContext
{
    [SerializeField] private MyCustomComponent _customComponent;

    protected override void PreCacheCommonComponents()
    {
        base.PreCacheCommonComponents();  // Caches NavMeshAgent, Animator, AudioSource
        if (_customComponent != null)
            CacheCapability(_customComponent);
    }
}

Strategies access cached components via context.GetCapability<T>() with O(1) lookup time.


See Also

  • The Planning Loop — How the planner, executor, and FSM interact each frame
  • Blackboard — The key-value store that drives all decision-making
  • Performance Tuning — Scaling guidelines for the Inspector settings above
  • Glossary — Quick definitions for all framework terms

What's Next