Quest Manager
QuestManager.cs
Overview
QuestManager is the central authority of the Quest Forge system. It owns all quest state — tracking which quests are active, completed, failed, or abandoned — and provides the public API for starting, completing, failing, and abandoning quests. It also listens to the QuestEventBus to automatically advance quest objectives as gameplay events occur, manages the Quest Journal UI, drives the HUD tracker display, and runs per-frame objective distance calculations.
QuestManager is a singleton MonoBehaviour resolved via QuestManager.Instance. It should be present in the scene as part of the QuestForgeManagers prefab.

Inspector Properties
Quest Registry
All Quests
The master list of every Quest ScriptableObject in the game. Quests must be registered here to be tracked or started.
Debug Mode
Enables verbose logging via QuestLogger for all quest state changes and event processing.
Give Quest Animation
When enabled, the NewQuestPanel animation plays on quest start, completion, and failure. The panel waits for any in-progress dialogue to finish before displaying.
UI References
Quest Journal UI
The root GameObject of the Quest Journal panel. Toggled by OpenQuestJournal() / CloseQuestJournal().
Quest UI Child Prefab
Prefab instantiated for each quest entry in the journal's quest list.
Quest Category Header Prefab
Prefab used to create category headers (Active, Completed, Failed) in the journal list.
Objective UI Child Prefab
Prefab instantiated for each objective in the journal's objective panel.
Quest Reward UI Child Prefab
Prefab instantiated for each reward shown in the journal's reward panel.
Quest UI Parent
The Transform (ScrollView content) that quest list items are parented to.
Objective UI Parent
The Transform (ScrollView content) that objective items are parented to.
Rewards UI Parent
The Transform (ScrollView content) that reward items are parented to.
No Quests / No Objectives / No Rewards Panel
GameObjects shown when the corresponding list is empty.
New Quest Panel
The notification panel shown on quest start, completion, or failure.
Quest Name Text
TextMeshProUGUI displaying the name of the currently selected journal quest.
Quest Description Text
TextMeshProUGUI displaying the description of the currently selected journal quest.
Current Tracked Quest UI Text
HUD element displaying the name of the currently tracked quest.
Current Tracked Quest Current Objective UI Text
HUD element displaying the current objective progress text for the tracked quest.
Objective Animation
Objective Animator
Animator triggered with "ObjectiveChange" when the tracked quest's current objective text changes.
Tracked Icon
GameObject shown when a quest is actively tracked. Hidden when nothing is tracked.
Text Fade Duration
Duration in seconds for the fade transition when the tracked objective text changes.
Quest Objective Distance Tracking
Enable Objective Tracking
Toggles per-frame distance calculation for all active quest objectives.
Show Distance To Objectives
Controls whether distance text is generated.
Distance Format
Format string for distance display (e.g. "0m" → 125m, "0.0m" → 125.5m).
Use Metric Units
When enabled, displays metres. When disabled, multiplies by Meters To Feet and displays in feet.
Meters To Feet
Conversion multiplier when imperial units are used (default 3.28084).
Objective Highlighting
Highlight Tracked Objectives
Enables the pulse highlight colour effect for tracked objective markers.
Tracked Objective Color
Target colour for the pulse animation on tracked objectives.
Tracked Objective Pulse Speed
Speed of the PingPong pulse cycle.
Tracked Objective Scale Multiplier
Scale factor returned for tracked objectives to increase their marker size.
Distance Ranges
Close Range
Distance threshold (metres) below which closeRangeColor is returned. Default 25.
Medium Range
Distance threshold (metres) below which mediumRangeColor is returned. Default 100.
Close / Medium / Far Range Color
Colours returned to callers for distance-based UI colouring (green / yellow / red by default).
Priority System
Prioritize Closest Objective
Orders GetPriorityObjectives() results by tracked status, required status, then distance.
Max Visible Objectives
Maximum number of results returned by GetPriorityObjectives().
Player Reference
Player Transform
TransformReference pointing to the player. Used for distance calculations and as instigator on events.
Auto Find Player
If enabled and Player Transform is not set at runtime, searches for a GameObject tagged "Player" on Start.
Malbers Events
These MEvent fields appear at the top of the component and are fired globally in addition to any quest-specific events:
EnemyKilledEvent
(Legacy integration point) — an enemy kill is reported via the legacy HandleEnemyKilled path.
ItemCollectedEvent
(Legacy integration point) — an item collection is reported via the legacy HandleItemCollected path.
LocationReachedEvent
(Legacy integration point) — a location is reported via the legacy HandleLocationReached path.
NPCTalkedToEvent
(Legacy integration point) — an NPC interaction is reported via the legacy HandleNPCTalked path.
OnQuestAbandoned
MEvent(string) — a quest is abandoned. Passes the quest ID.
OnQuestCompleted
MEvent(string) — a quest is completed. Passes the quest ID.
OnQuestFailed
MEvent(string) — a quest is failed. Passes the quest ID.
OnQuestStarted
MEvent(string) — a quest is started. Passes the quest ID.
UnityEvent
OnRewardGranted
UnityEvent<QuestRewardBase, QuestInstance>
A reward is successfully granted on quest completion. Passes the reward and the quest instance.
Quest Lifecycle API
StartQuest(string questId) → bool
StartQuest(string questId) → boolStarts a quest by its ID. Returns true if successful.
Checks:
Quest must exist in
allQuestsQuest must not already be active or completed (unless
Repeatable)Quest must not be in the failed list
All prerequisite quests must be completed (or at least one, if
PrerequisiteModeisRequireAny)
On success:
Creates a new
QuestInstance, sets status toActiveSubscribes the quest's objectives to the event bus
Fires
Quest.OnQuestStarted,QuestManager.OnQuestStarted(MEvent)Publishes
QuestProgressEventDatawith typeQuestStartedto the event busDisplays the New Quest Panel animation (if
Give Quest Animationis enabled, waits for active dialogue to finish first)
StartQuestWithID(string id)
StartQuestWithID(string id)Non-returning wrapper around StartQuest. Suitable for use as a Unity Event target.
CompleteQuest(string questId) → bool
CompleteQuest(string questId) → boolCompletes an active quest by its ID. Returns true if successful.
On success:
Moves the quest from
activeQueststocompletedQuestsGrants all rewards via
GrantQuestRewards()Fires
Quest.OnQuestCompleted,QuestManager.OnQuestCompleted(MEvent),OnRewardGranted(UnityEvent) per rewardPublishes
QuestProgressEventDatawith typeQuestCompletedRe-evaluates which quests are now available (
RefreshAvailableQuests)Displays the Quest Complete Panel animation
FailQuest(string questId) → bool
FailQuest(string questId) → boolFails an active quest by its ID. Returns true if successful.
On success:
Moves the quest from
activeQueststofailedQuestsFires
Quest.OnQuestFailed,QuestManager.OnQuestFailed(MEvent)Publishes
QuestProgressEventDatawith typeQuestFailedDisplays the Quest Failed Panel animation
AbandonQuest(string questId) → bool
AbandonQuest(string questId) → boolAbandons an active quest by the player's choice. Returns true if successful.
On success:
Moves the quest from
activeQueststoabandonedQuestsFires
Quest.OnQuestAbandoned,QuestManager.OnQuestAbandoned(MEvent)If the quest is
Repeatable, adds it back toavailableQuests
Quest State Queries
IsQuestActive(string questId)
bool
Whether the quest is currently in the active state.
IsQuestCompleted(string questId)
bool
Whether the quest has been completed.
IsQuestAvailable(string questId)
bool
Whether the quest's prerequisites are met and it can be started.
GetActiveQuest(string questId)
QuestInstance
The active QuestInstance for the given ID, or null.
GetActiveQuests()
List<QuestInstance>
All currently active quest instances.
GetCompletedQuests()
List<QuestInstance>
All completed quest instances.
GetFailedQuests()
List<QuestInstance>
All failed quest instances.
GetAbandonedQuests()
List<QuestInstance>
All abandoned quest instances.
GetAvailableQuests()
List<Quest>
All Quest ScriptableObjects that can currently be started.
GetAvailableQuestIds()
List<string>
IDs of all quests that can currently be started.
GetActiveQuestCount()
int
Total number of currently active quests.
GetCompletedQuestCount()
int
Total number of completed quests.
GetQuestDefinition(string questId)
Quest
The Quest ScriptableObject for a given ID, from allQuests.
ForceRefreshAvailableQuests()
void
Re-evaluates all prerequisite checks and rebuilds the available quests set. Call after loading a save.
Objective State Queries
IsObjectiveCurrentlyActive(string questId, string objectiveId)
bool
Returns true if the specified objective is the current active (first incomplete) objective in its quest.
IsObjectiveCompleted(string questId, string objectiveId)
bool
Returns true if the specified objective has been completed in an active quest.
Quest Tracking API
Only one quest can be tracked at a time. The tracked quest is displayed on the HUD and drives the minimap/compass objective indicator.
TrackQuest(QuestInstance quest)
Sets the given quest as tracked. Automatically untracks all other active quests.
UntrackQuest(QuestInstance quest)
Removes tracking from the given quest.
UntrackAllQuests()
Removes tracking from all active quests.
GetCurrentTrackedQuest()
Returns the first QuestInstance with isTracked = true, or null if none.
Objective Distance Tracking API
Each frame (when Enable Objective Tracking is on), QuestManager builds a Dictionary<string, QuestObjectiveData> mapping objective IDs to their distance data. This data is consumed by the compass, minimap, and any custom UI.
GetAllObjectiveData()
Dictionary<string, QuestObjectiveData>
All current objective distance data for all active quests.
GetObjectiveData(string objectiveId)
QuestObjectiveData
Distance data for a specific objective ID.
GetClosestObjective()
QuestObjectiveData
The objective with the shortest distance to the player that has a world position.
GetTrackedObjectives()
List<QuestObjectiveData>
Returns only the current active (first incomplete) objective of the tracked quest. Used by the HUD.
GetQuestObjectives(string questId)
List<QuestObjectiveData>
All objective data entries belonging to the specified quest.
GetPriorityObjectives()
List<QuestObjectiveData>
Top N objectives ordered by: tracked first, required before optional, then closest. N is set by Max Visible Objectives.
GetObjectiveWorldPosition(QuestObjective objective)
Vector3?
Returns the world position for an objective — directly from GoToLocationObjective.targetPosition, or from a linked PointOfInterest via POIManager. Returns null if no position can be determined.
ShouldHighlightObjective(string objectiveId)
bool
Returns true if the objective belongs to the tracked quest and highlighting is enabled.
GetObjectiveHighlightColor(string objectiveId, float pulseTime)
Color
Returns the pulsed highlight colour for the objective based on Time.time. Returns white if not highlighted.
GetObjectiveScaleMultiplier(string objectiveId)
float
Returns trackedObjectiveScaleMultiplier for tracked objectives, 1f otherwise
Quest Journal UI API
These methods are typically called by UI buttons or input handlers.
OpenQuestJournal()
Activates the Quest Journal UI GameObject.
CloseQuestJournal()
Deactivates the Quest Journal UI GameObject.
ToggleQuestJournal()
Toggles the journal open/closed. Will not open if dialogue is currently active. Refreshes quest and objective lists when opening.
PopulateQuestUIList()
Rebuilds the full quest list in the journal, grouped by Active, Completed, and Failed categories.
PopulateObjectiveUIList()
Rebuilds the objective list for currentlySelectedQuest.
PopulateRewardsUIList()
Rebuilds the rewards list for currentlySelectedQuest.
SelectQuest(QuestInstance questInstance)
Sets the given quest instance as the currently selected journal entry and refreshes the details, objectives, and rewards panels.
SelectQuestById(string questId)
Finds a quest by ID (checking active then completed) and selects it.
UpdateCurrentTrackedQuestUI()
Refreshes the HUD tracker text with the current tracked quest name and objective progress. Triggers the fade animation if the objective text has changed.
How It Works
On Awake, QuestManager subscribes to five event types on the QuestEventBus:
EnemyKilled→ increments kill counts viaQuestProgress.AddKill(key)ItemCollected→ increments item counts viaQuestProgress.AddItem(itemId, quantity)NPCTalkedTo→ setstalked_to_{npcId}flags (andtalked_to_{npcId}_{dialogueId}if a dialogue ID is present)LocationReached→ setsreached_{locationId}flagsObjectInteracted→ records interactions viaQuestProgress.AddInteraction(id, instanceId)and also tracks byMInteract.Indexif provided
After any event is processed, CheckQuestProgress() is called on all active quests. This calls QuestInstance.UpdateObjectiveStatus() and QuestInstance.CheckCompletion(). If all required objectives are satisfied, CompleteQuest() is called automatically.
A QuestProgressEventData event is published to the bus after every progress check, allowing other systems (such as POIMarker visibility logic) to react to objective changes without polling.
Other Notes
QuestManageris notDontDestroyOnLoad— unlikeQuestEventReporter, it lives in the scene. If you load a new scene, ensure aQuestManageris present or the system will not function. Quest state is maintained via the save system across scene loads.Prerequisite logic supports two modes:
RequireAll(all prerequisites must be complete) andRequireAny(at least one must be complete). This is defined on the Quest ScriptableObject.The New Quest / Complete / Fail animations wait one frame after the event fires before checking if dialogue is active. This prevents race conditions when a
QuestTriggerand a dialogue trigger fire on the same frame.Repeatablequests re-enter theavailableQuestsset after abandonment and can be re-entered theavailableQuestsset after completion ifquestTypeisRepeatable.Call
ForceRefreshAvailableQuests()after loading a save file to ensure the available quest set correctly reflects the loaded completed quest list.
Last updated