Interact Objective

Overview

InteractObjective tracks player interactions with world objects. It listens to QuestEventType.ObjectInteracted events published via the QuestEventBus and advances its progress count when an event matches its configured target.

It is one of the most flexible objective types, capable of handling four distinct interaction scenarios:

  • Single interaction — "Pull the lever" (one interaction required, shows ✓/✗)

  • Multiple of same type — "Read 3 ancient tomes" (interact with the same or different instances of the same type)

  • Unique instances — "Light 5 different torches" (must interact with five distinct objects, not the same one repeatedly)

  • Index-based matching — Match by Malbers MInteract.Index instead of a string ID

InteractObjective is added as an objective entry on a Quest ScriptableObject. It is not a component — it is a serialized data class. The corresponding scene component that fires events is QuestInteractable.

Fields

Interact Objective Settings

Field
Type
Description

Interactable ID

string

The string identifier this objective listens for. Must match the interactableId set on the corresponding QuestInteractable component(s) in the scene.

Interactable Name

string

Display name used in progress text (e.g. "Torch""Interact with 5 different Torches: 2/5").

Required Interactions

int

How many interactions are needed to complete this objective. Default 1.

Require Unique Instances

bool

When true, each interaction must come from a different object instance. Interacting with the same object multiple times counts only once. When false, any interaction matching the ID increments the counter.

MInteract Integration

Field
Type
Description

Match By Index

bool

When enabled, also attempts to match incoming events by MInteract.Index value rather than string ID alone.

Interact Index

int

The MInteract.Index value to match. Only evaluated when Match By Index is enabled and the index is greater than 0.


Inherited Fields (from QuestObjective)

Field
Type
Description

Objective ID

string

Auto-generated GUID uniquely identifying this objective within its quest.

Description

string

Text shown to the player describing what to do. Displayed in the Quest Journal and HUD tracker.

Is Optional

bool

When true, this objective does not need to be completed for the quest to complete.

How It Works

Matching

When an ObjectInteractedEventData event arrives, the objective checks for a match using the following logic:

  1. If interactableId is set and matches eventData.interactableIdmatch

  2. If no match from ID, and matchByIndex is true and interactIndex > 0 and matches eventData.interactIndexmatch

If either condition is true, QuestManager records the interaction via QuestProgress.AddInteraction(key, instanceId).

Progress Tracking Key

The key used to store progress in QuestProgress is determined in this priority order:

  1. interactableId — if set, used directly as the key

  2. interact_index_{interactIndex} — if matchByIndex is enabled and index > 0

  3. interact_{objectiveId} — fallback using the objective's own GUID

This key is the same value used by both CheckCompletion and GetProgressText, so they always read the same data.

Unique Instance Tracking

When Require Unique Instances is true, the objective calls QuestProgress.GetUniqueInteractionCount(key) instead of GetInteractionCount(key). The QuestProgress system tracks which instance IDs have already been recorded for a given key and ignores duplicates. The instance ID comes from QuestInteractable's runtimeInstanceId field, which is auto-generated as {sceneName}_{instanceID} unless overridden with a custom value.

Completion Check

Event Subscription Lifecycle

When the parent quest starts, QuestManager calls SubscribeToEvents(eventBus) on this objective. It subscribes to QuestEventType.ObjectInteracted. When the quest ends (completed, failed, or abandoned), UnsubscribeFromEvents(eventBus) is called, removing the subscription. Subscriptions are guarded against duplicates — subscribing twice has no effect.


Progress Text Formats

Scenario
Example Output

Single interaction, not complete

Interact with object: ✗

Single interaction, complete

Interact with object: ✓

Multiple, same instance allowed

Interact with 3 different Shrines: 1/3

Multiple, unique instances required

Interact with 5 different Torches: 2/5


Connecting to the Scene

InteractObjective requires a matching QuestInteractable component on the world object(s) the player interacts with. The interactableId on the objective and the interactableId on the QuestInteractable must be identical strings.

Quest ScriptableObject
Scene Object

InteractObjective.interactableId = "Shrine"

QuestInteractable.interactableId = "Shrine"

InteractObjective.interactIndex = 3 (with matchByIndex)

MInteract.Index = 3 on the same GameObject

For unique instance tracking to work, QuestInteractable.useUniqueInstanceId must be enabled (it is on by default), ensuring each object reports a different instance ID.


Example Configurations

"Pull the lever" — single, any instance

"Read 3 notice boards" — multiple, same object allowed

"Light 5 different torches" — multiple, must be unique objects

"Activate the crystal" — index-based matching


Other Notes

  • interactableId matching takes priority over index matching. If both are set and the ID matches, the index is never evaluated.

  • If neither interactableId is set nor matchByIndex is enabled, the objective will never match any event and cannot be completed. A warning is not thrown automatically — verify your configuration during development.

  • Setting requiredInteractions to 1 with requireUniqueInstances = true is functionally identical to requireUniqueInstances = false — it makes no difference whether the single interaction comes from a unique instance or not.

  • The progress tracking key is determined at runtime from the same field values used during design time, so keys are stable and consistent across quest save/load cycles.

Last updated