Page 1 of 1
HasOfferableOrActiveQuest returning false when active quest
Posted: Wed Apr 27, 2022 3:28 pm
by mroshaw
Hi!
I'm calling "QuestGiver.HasOfferableOrActiveQuest()" in order to determine whether or not to show a minimap icon for a Quest Giver. I call this via an Event triggered by the OnQuestStateChanged message, so I basically re-evaluate the minimap icon state whenever a Quest state changes.
I have the Quest Giver give a quest to my player via GiveQuestToQuester(), after which I call QuestGiver.HasOfferableOrActiveQuest() and get "false" in response.
I understood there to be an "active quest" in the context of that QuestGiver, until such time as the player completes, fails or abandons the quest. So I expected QuestGiver.HasOfferableOrActiveQuest() to return true.
Have I got the wrong end of the stick with how this function works, or am I doing something wrong, do you think?
Thanks again!
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Wed Apr 27, 2022 4:06 pm
by Tony Li
Hi,
That's how it should work.
If you're finding that it isn't working that way, would you please provide reproduction steps?
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Wed Apr 27, 2022 5:14 pm
by mroshaw
Hi Tony and thanks again for the swift response.
From my perspective, I reproduce this by doing what I described:
- Add "Message Events" component and hook up an Event handler to "OnQuestStateChanged"
- In the Event handler, call "QuestGiver.HasOfferableOrActiveQuest()"
- Call "GiveQuestToQuester()" on NPC game object "Dialog System Quest Giver" component
And what happens for me is that the Quest successfully appears in the Player Journal, but the result of the Event handler code is that HasOfferableOrActiveQuest() is false when it should be true.
Is there anything I can debug, or particular aspects of the runtime environment that I can inspect, to try to figure out what's going on?
Thanks!
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Wed Apr 27, 2022 6:23 pm
by Tony Li
I'll set up reproductions of both of these issues and let you know what I see. If you want to get a jump on that, you could also put a breakpoint on the QuestGiver.HasOfferableOrActiveQuest() method and step through it. But I'm going to do the same, so feel free to wait until I reply back with an answer.
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Wed Apr 27, 2022 8:46 pm
by Tony Li
Hi,
If you wait until the end of the frame, QuestGiver.HasOfferableOrActiveQuest() will be true.
In other words, instead of this method:
Code: Select all
public void CheckHasActiveOrOfferable()
{
Debug.Log("HasOfferableOrActiveQuest = " + GetComponent<QuestGiver>().HasOfferableOrActiveQuest());
}
use this method:
Code: Select all
public void CheckHasActiveOrOfferable()
{
StartCoroutine(CheckCoroutine());
}
IEnumerator CheckCoroutine()
{
yield return new WaitForEndOfFrame();
Debug.Log("HasOfferableOrActiveQuest = " + GetComponent<QuestGiver>().HasOfferableOrActiveQuest());
}
This is because the "Quest State Changed" message is sent multiple times as the quest giver's and player's copies of the quest go through several changes. Here's an annotated log of using the first (incorrect) method above:
- questActiveBreakdown.png (109.17 KiB) Viewed 1084 times
(I also ticked Quest Machine's Debug checkbox to log info about what activity triggered each "Quest State Changed" message.)
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Thu Apr 28, 2022 8:30 am
by mroshaw
Thanks Tony! There's still something weird going on, as even after adding a debug button that calls HasOfferableOrActiveQuest, I'm getting "false".
I've stuck a breakpoint into the code and am debugging. What I'm finding is that when it gets to "RecordRelevantPlayerQuests" , "playerQuestListContainer" is null. Same with "RecordOfferableQuests", so the net results is that those two methods always return 0, hence the whole method always returns false:
Code: Select all
if (playerQuestListContainer == null || playerQuestListContainer.questList == null) return;
I just need to work out why this is null, and then I think I'm on to a winner!
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Thu Apr 28, 2022 8:46 am
by mroshaw
Right, I think I might see what's happening here.
In my scene, the Quest Journal is not a component of the Player. I spawn a player prefab depending on what character is selected at the start of the game. To keep things simple, I have the Quest Journal as a Game Object directly within the scene.
The Quest Machine code, certainly within the context of Quest Giver methods, seems to assume that the Quest Journal, or equivalent container, is a component of the player Game Object:
Code: Select all
if (m_playerQuestListContainer == null && player != null) m_playerQuestListContainer = player.GetComponent<QuestListContainer>();
In my case, that's not true.
There may be a very good reason NOT to do this, but if I replace the line about in QuestGiver.cs with this:
Code: Select all
if (m_playerQuestListContainer == null && player != null) m_playerQuestListContainer = QuestMachine.GetQuestJournal();
Then everything springs to life!
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Thu Apr 28, 2022 9:04 am
by Tony Li
Here are a couple of options you can use without having to resort to changing the code:
- You can pass your Quest Journal GameObject to QuestGiver.HasOfferableOrActiveQuest(GameObject). This makes it completely unambiguous.
- Or you can set your Quest Journal GameObject's tag to Player. This will allow QuestGiver.HasOfferableOrActiveQuest() to find it.
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Thu Apr 28, 2022 10:26 am
by mroshaw
Amazing! Problem solved! Thank you so much again!
Re: HasOfferableOrActiveQuest returning false when active quest
Posted: Thu Apr 28, 2022 10:55 am
by Tony Li
Glad to help!