Trigger Volumes
A ConversationTriggerVolume starts a player conversation when the player walks into a trigger collider. It is how you build the moment where a guard stops you at the gate, or a shopkeeper calls out as you pass, without the player having to look at anyone and press Interact.
It is a different mechanism from Conversation Triggers, which start conversations between agents. A trigger volume always starts a player conversation.
Setting one up
- add an empty GameObject where you want the trigger, and give it a
Colliderwith Is Trigger ticked - add
ConversationTriggerVolume-- the collider is a required component, so Unity adds one if you skip step 1 - assign Npc Chat Agent to the
AgentChatServicethe player should talk to
The volume needs the chat agent rather than a bare agent because the chat agent is what owns the tree -- its presence is what guarantees there is actually a conversation to have. If you leave the field empty, the volume looks for one on its own GameObject and parents.
Any collider entering the volume is checked for an IAgentService whose ID is player. A player rig usually has several colliders; only the first to arrive counts, and the volume is not considered empty until all of them have left.
Repeat behaviour
| Setting | Default | What it does |
|---|---|---|
| Repeat Mode | Repeatable | Once fires a single time for the lifetime of the scene. Repeatable allows re-entry. |
| Require Exit To Rearm | on | The player must leave the volume before it can fire again. Prevents instant re-triggering. |
| Cooldown Seconds | 0 | Minimum time before the volume can fire again, measured from the end of the last conversation. |
Measuring the cooldown from the end rather than the start is what stops a long conversation from being immediately repeatable the moment it finishes.
ResetTriggerState() clears all three at once, which is what you call from a quest script to make a one-shot volume live again.
Conversation behaviour
| Setting | Default | What it does |
|---|---|---|
| End Conversation When Player Leaves | on | Walking out of the volume ends the conversation. Turn off for a conversation the player must finish. |
| Interrupt Ongoing Conversation | off | Fire even if the NPC or the player is already in a conversation. |
| Ignore Availability Checks | off | Skip the availability checks that would normally refuse the conversation. |
Ignore Availability Checks bypasses IConversationAvailabilityCheck implementations -- including CivilAI's, which refuses conversation with an agent whose current job should not be interrupted. Use it for scripted story beats that must happen regardless.
Even with both bypasses on, a volume will not start a conversation while another one is already on screen.
Requirements
Two RequirementCollection fields gate the trigger:
- Npc Requirements -- evaluated against the NPC
- Player Requirements -- evaluated against the player
RequirementCollection is a shared BardTreeLtd type, not a dialogue-specific one. See the Requirement System guide in the CIVIL-AI docs for how to author one.
Both must pass. This is what makes a volume conditional on story state -- a gate guard who only stops you before you have the pass.
Overrides
Each volume carries a ConversationOverrides block, letting this one conversation behave differently from the module defaults. See Conversation Policies.
Overrides are pushed before the conversation opens and cleared when it finishes, including when it fails to start.
Why a volume did not fire
Evaluate returns a ConversationVolumeGateResult naming the reason, and with debug mode on that reason is logged as Volume <name> skipped: <reason>.
| Result | Meaning |
|---|---|
Allowed | The conversation will be attempted. |
NoNpcAgent | No chat agent is assigned or resolvable. |
NotPlayer | The entering collider does not belong to the player agent. |
AlreadyTriggered | Repeat mode is Once and it has already fired. |
AwaitingExit | The player has not left since the last trigger. |
OnCooldown | The cooldown has not elapsed. |
NpcPaused | The NPC's pause service reports it as paused. |
ParticipantBusy | Either participant is already in a conversation. |
RequirementsNotMet | The NPC or player requirements failed. |
NpcUnavailable | An availability check refused the conversation. |
Two more failures happen after the gate passes and are logged separately: the chat system service could not be resolved (there is no dialogue UI in the scene), and the conversation closed the instant it opened. The second usually means the tree failed to resolve or its first node is an end node.
Neither case counts as a trigger, so a Once volume that failed this way is still live and will fire again once you fix the cause.
See Debugging for turning debug logging on.
Public API
| Name | Parameters | Return Type | Description |
|---|---|---|---|
| Evaluate | IAgentService candidatePlayer, float now | ConversationVolumeGateResult | Runs the gate without side effects. now is a parameter so it can be tested outside play mode. |
| TryBeginConversation | IAgentService candidatePlayer | bool | Evaluates and, if allowed, opens the conversation. |
| EndOwnedConversation | N/A | void | Ends the conversation this volume started. |
| ResetTriggerState | N/A | void | Clears triggered, armed, and cooldown state. |
Read-only properties expose every inspector field, plus IsOwningConversation and HasTriggered.
Practical advice
Start with the defaults. Repeatable plus require-exit-to-rearm plus end-when-the-player-leaves is the behaviour players expect from an ambient world, and it is hard to get stuck in.
Reach for Once only for content that genuinely happens a single time, and remember that it does not survive a scene reload on its own -- if the moment should stay spent across sessions, gate it on a blackboard value instead and leave the volume repeatable.
Keep volumes generously sized. A trigger the player can clip past at a sprint reads as a bug, not a missed optional conversation.
Reference
Next step
Continue to Responses and Options.