How to load a quest asset? (Properly??)

Announcements, support questions, and discussion for Quest Machine.
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

How to load a quest asset? (Properly??)

Post by erikbethke »

Hello Tony,

(Unity 2020.1.6f1 using quest machine 1.2.11)

New user here. Read the manual a few times, watched the videos and stepped through some of the code.

I have been able to write a new quest from scratch, add conditions, with QuestBuilder and everything works as expected.

Naturally, though, I would like to use your quest editor to make some quests. So I did.

Followed the tutorials, and my quest is a simple Start > Condition > Success and I added it to a new quest database that I created for my project and added to quest machine.

But when I play, the counter messages come through and I can see progress using {#counter} and {<#counter}, but they never trigger the Success node.

So, I have been debugging, and I noticed that the hand scripted quest is an Instance, and is not an Asset. And the ones that I created in the editor are reversed: they are Assets and not Instances.

Also, explains why the current counter is modified for the quest editor created quests in the project folder and I have to keep re-setting them to 0!

In both cases I just call:
mainCamera.GetComponent<QuestJournal>().AddQuest(quest);
mainCamera.GetComponent<QuestJournal>().AddQuest(qa);

(mainCamera ** is ** the "player" in my game with the quest journal component.)

Where qa is:
var qa = Resources.Load("Quests/Place3Solarpanels") as Quest;

And quest is the working quest that is hand crafted in code (that is working just fine)

So, what is the proper pattern for using the Quest Editor to make the quests, but load them at run-time and assign them to the player?

I got excited by:
QuestMachine.RegisterQuestAsset(qa);
var quest2 = QuestMachine.GetQuestInstance("Place3SolarPanels");

But this triggers a warning that qa is not an asset and so it does not register
And then of course quest2 becomes null

So, I am missing some sort of basic pattern for how you intended this to work.

What am I doing wrong?

Thank you,
-Erik
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to load a quest asset? (Properly??)

Post by Tony Li »

Hi Erik,

Hmm, if you created a quest asset in the Quest Editor, its 'isInstance' property should be false. If 'isInstance' is false, then QuestJournal.AddQuest() should create an instance of the asset and add the instance to its list, not the original asset. QuestJournalAddQuest() returns the instance that was just added to its list:

Code: Select all

Quest questInstance = myQuestJournal.AddQuest(questAsset);
Please temporarily change your Inspector view to Debug mode and inspect the quest asset. Is Is Instance false (unticked)?

questAssetNotInstance.png
questAssetNotInstance.png (28.18 KiB) Viewed 750 times

How are you incrementing the counter? Are you incrementing the quest asset directly? (If so, don't do that.) Or are you working with the QuestJournal's instance of the quest? Or, better yet perhaps, using messages to increment it?


Note: If you need to create a new instance of a quest, use Quest.Clone():

Code: Select all

Quest newCopyOfQuest = originalQuest.Clone();

Another note: It's best if you can also assign those quest assets in Resources to your quest database. This way when you're loading a saved game the QuestJournal will be able to find the right quest asset to instantiate.

If you can't assign them to a quest database, then use QuestMachine.RegisterQuestAsset() to let Quest Machine know about the quest asset.
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

Re: How to load a quest asset? (Properly??)

Post by erikbethke »

Hello Tony,

Thank you very much for the fast and thorough reply!

Okay, so it turned out that the IsInstance for that QuestEditor made quest, was indeed checked. I got excited, and un-checked it, and I am still having the same problem that the counters increase but it does not trigger the success state.

And yes, I am using the message system to increment the counters like this:
MessageSystem.SendMessage(this, "Place" , "Solar", 1);

For the hand-written quest I do the same:
MessageSystem.SendMessage(this, "Place" , "Rover", 1);

And this one does successfully trigger the success state:

I do have the solar panel quest in the Database - should I be instantiating it from the database in some method?
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

Re: How to load a quest asset? (Properly??)

Post by erikbethke »

I tried:

var place3 = QuestMachine.GetQuestInstance("Place3SolarPanels");
place3.SetState(QuestState.Active);
mainCamera.GetComponent<QuestJournal>().AddQuest(place3);


Where "Place3SolarPanels" is the questID of the quest that is referenced in the quest DB...
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to load a quest asset? (Properly??)

Post by Tony Li »

Hi Erik,

You don't need to instantiate it from the database. Now that Is Instance is unticked, just pass your quest to QuestJournal.AddQuest().

Are you activating the quest? Example:

Code: Select all

var questInstance = myQuestJournal.AddQuest(questAsset);
questInstance.SetState(QuestState.Active);
QuestMachineMessages.RefreshIndicators(questInstance);
The ideal way to assign a quest to a QuestJournal is to use a QuestGiver. You can create an empty GameObject with a QuestGiver component. It doesn't have to have a physical representation of an NPC in the scene. Assign the quest to the QuestGiver's list in the editor or by calling QuestGiver.AddQuest(). Then allow the QuestGiver to give the quest to the QuestJournal:

Code: Select all

myQuestGiver.GiveQuestToQuester(myQuestGiver.FindQuest("quest id"), myQuestJournal);
This does a lot of internal housekeeping, including the code shown above. The full code that it runs on the quest journal and its quest instance is:

Code: Select all

// Make a copy of the quest for the quester:
var questInstance = quest.Clone();

// Add the copy to the quester and activate it:
questInstance.AssignQuestGiver(myQuestGiverTextInfo);
questInstance.AssignQuester(questerTextInfo);
questInstance.timesAccepted = 1;
if (questerQuestListContainer.questList.Count > 0)
{
	for (int i = questerQuestListContainer.questList.Count - 1; i >= 0; i--)
	{
		var inJournal = questerQuestListContainer.questList[i];
		if (inJournal == null) continue;
		if (StringField.Equals(inJournal.id, quest.id) && inJournal.GetState() != QuestState.Active)
		{ // Journal had an old copy. Delete it to make room for the new copy:
			questInstance.timesAccepted++;
			questerQuestListContainer.DeleteQuest(inJournal);
		}
	}
}
questerQuestListContainer.deletedStaticQuests.Remove(StringField.GetStringValue(questInstance.id));
questerQuestListContainer.AddQuest(questInstance);
questInstance.SetState(QuestState.Active);
QuestMachineMessages.RefreshIndicators(questInstance);
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

Re: How to load a quest asset? (Properly??)

Post by erikbethke »

It seems to be registering the quest properly on start-up:

Quest Machine: Registering quest asset 'Place3SolarPanels'.
UnityEngine.Debug:Log(Object, Object)
PixelCrushers.QuestMachine.QuestMachine:RegisterQuestAsset(Quest) (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest Machine/QuestMachine.cs:216)
PixelCrushers.QuestMachine.QuestMachineConfiguration:RegisterQuestDatabases() (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest Machine/QuestMachineConfiguration.cs:315)
PixelCrushers.QuestMachine.QuestMachineConfiguration:Awake() (at Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest Machine/QuestMachineConfiguration.cs:251)
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to load a quest asset? (Properly??)

Post by Tony Li »

Our posts crossed. :-) If my reply above doesn't help, please let me know.
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

Re: How to load a quest asset? (Properly??)

Post by erikbethke »

Despite your awesome service, I am still not being able to get the Quest Editor script(s) to transition to successful.

New steps taken:
1) Created an empty game object as you suggested, (I called it Quest Manager) and added the Quest Giver component.

2) Added the Place3SolarPanels Quest Editor created quest to the Quest Giver (and two more just like it - simple, single condition counter quests)

3) I then find the quests and assign them to the quest journal using your suggested method:

Code: Select all

        var questGiver = questManager.GetComponent<QuestGiver>();
        var questJournal = mainCamera.GetComponent<QuestJournal>();
        
        questGiver.GiveQuestToQuester(questGiver.FindQuest("Place3SolarPanels"), questJournal);
        questGiver.GiveQuestToQuester(questGiver.FindQuest("PlaceBattery"), questJournal);
        questGiver.GiveQuestToQuester(questGiver.FindQuest("PlaceFuelCell"), questJournal);
4) I see the quests added to the journal, no problem.

5) I Drop 3 Rovers to satisfy the hand-written quest and it transitions to successful

6) I then Drop Solar Panels (and try again with Fuel Cells and Batteries) and yes the counters increment, but it does not transition to successful.

Image

For the condition I have it:
ConditionCountMode: All (but there is only 1 condition anyways)
Counter: SolarPanelsPlaced
Counter Value Mode: At Least
Required Counter Value: Literal, 3

Image

What should I check or try next?

Thank you again for your great help.

-Erik
User avatar
Tony Li
Posts: 21925
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to load a quest asset? (Properly??)

Post by Tony Li »

Hi Erik,

Let's take a look at the Place3SolarPanels quest. If you inspect the QuestJournal during play does it look like this:

place3SolarPanelsExample.png
place3SolarPanelsExample.png (22.64 KiB) Viewed 740 times

Also, let's make sure nothing has gone wrong with your Quest Machine installation. Does Quest Machine's Demo scene play correctly? For example, can you talk to the Villager and complete the Harvest 3 Carrots quest?
erikbethke
Posts: 8
Joined: Thu Oct 15, 2020 5:40 pm

Re: How to load a quest asset? (Properly??)

Post by erikbethke »

Yes, during run time the Place 3 Solar Panels quest is the same as you show (runtime:Active, True for Start and Active for the condition node).

I switched to the Demo scene that is **part** of my current project.

And I was able to complete both quests with Johann and kill the orcs for the knights. So Quest Machine itself seems very healthy...
Post Reply