Page 1 of 1

Get Current Quest Nodes

Posted: Sat Dec 09, 2023 8:16 am
by chrisp1985
Hello,

I've been looking through the scripting documentation to try to find a way to access the current quest and its nodes. I'm hoping to use questmachine to show the player the distance to the current objective. I'm working an AR game and have created a compass and a distance indicator (see example). I was hoping to use the current active quest and the node to drive this information.

is it possible to use scripting to access a collider and then obtain its world location if the current node condition is based on a collider trigger?

im pretty new to questmachine so apologies if im not explaining my goals correctly. happy to expand/clarify.
distance example.png
distance example.png (122.61 KiB) Viewed 14329 times
thanks!

Re: Get Current Quest Nodes

Posted: Sat Dec 09, 2023 9:15 am
by Tony Li
Hi,

The player can have more than one quest active at a time. The player can also track more than one quest at a time unless you've ticked the Quest Journal component's UI Settings > Only Track One Quest At A Time.

In code, you can get a reference to the player quest journal using QuestMachine.GetQuestJournal():

Code: Select all

using PixelCrushers.QuestMachine; // (Put at top of script to gain access to Quest Machine API.)
...
QuestJournal journal = QuestMachine.GetQuestJournal();
To identify the currently-tracked quest, or the first tracked quest if you allow the player to track more than one at a time, check the journal's questList:

Code: Select all

var trackedQuest = journal.questList.Find(quest => quest.showInTrackHUD);
Once you have a reference to the quest, you can find the current active node:

Code: Select all

var activeNode = quest.nodeList(node => node.GetState() == QuestNodeState.Active);
From there, you need a way to associate a GameObject with the node. There are a few ways you could do this:
  • Add a quest content to the quest node's Active state > HUD Text. This could be a Body Text content such as "Track: <name>", or it could be a custom quest content type.
  • Or you could "repurpose" the node's Internal Name field to specify the target GameObject name.
  • Or, instead of all of the above, write a custom quest action that you can add to the quest node's Active state > Actions list. In this custom action, set the compass to point to a GameObject. This is what the built-in Set Quest Indicator quest action does.
If you use the first approach and set the content text to "Track: <name>", you could find it like this:

Code: Select all

QuestContent content = activeNode.GetContentList(QuestContentCategory.HUD)[0] as QuestContent;
string targetName = content.runtimeText;
GameObject target = GameObject.Find(targetName);
If you use the second approach:

Code: Select all

GameObject target = GameObject.Find(activeNode.internalName.value);

Related: To know when a quest has changed state, see How To: Respond To Quest State Changes in Script. You can use the same concept to be notified when a different quest is being tracked. In that case, listen for QuestMachineMessages.QuestTrackToggleChangedMessage.

Re: Get Current Quest Nodes

Posted: Sat Dec 09, 2023 10:17 am
by chrisp1985
Wow! Thanks Tony! Let me try implementing what you've suggested. I'll revert back with updates and any questions. Thanks again.

Re: Get Current Quest Nodes

Posted: Mon Dec 11, 2023 7:12 am
by chrisp1985
Hi Tony,

I'm trying to implement your suggestions. I'm stuck on setting the activeNode var:

Code: Select all

var activeNode = quest.nodeList(node => node.GetState() == QuestNodeState.Active);
(I assumed quest should be trackedQuest).

When I try to set activeNode it gives the following error: "Non-invocable member 'Quest.nodeList' cannot be used like a method."

Here's the full code so far:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers.QuestMachine;

// Get the currently active quest
public class QuestMachineCustomScripting : MonoBehaviour
{
    QuestJournal journal = QuestMachine.GetQuestJournal();

    void Start()
    {
        var trackedQuest = journal.questList.Find(quest => quest.showInTrackHUD);
        var activeNode = trackedQuest.nodeList(node => node.GetState() == QuestNodeState.Active);
        
    }
}
what am i doing wrong? thanks.

Re: Get Current Quest Nodes

Posted: Mon Dec 11, 2023 7:45 am
by Tony Li
Hi,

There were a couple of typos in that line. Please try:

Code: Select all

var activeNode = trackedQuest.nodeList.Find(node => node.GetState() == QuestNodeState.Active);