Using the Quest Machine UIs with the Dialogue System Integration

Announcements, support questions, and discussion for Quest Machine.
Post Reply
Codebread
Posts: 8
Joined: Sat Mar 28, 2020 4:16 pm

Using the Quest Machine UIs with the Dialogue System Integration

Post by Codebread »

Heyo!

I'm trying out both the Dialogue System and Quest Machine for the follow-up to our last game, having switched to Unity. I'm loving the features of each individually, and I have both conversations and quest machine quests set up independently. Today I finally integrated the two systems and it works like a charm. However, there's a single thing left that I'd like to do (or at least confirm is possible) before buying these packages.

Essentially, I want to still use the handy Quest Machine UIs when giving the player the option to accept or decline the quest, a well as the UI seen in the demo that allows you to choose between the multiple quests that the Quest Giver is offering. I'm imagining it like so:
  • Approach an NPC with a Quest Indicator and talk to them
  • If they have multiple quests you see a window that allows you to choose which quest to talk about
  • The quest offer text is displayed via the Dialogue System, allowing branching conversations, etc
  • On final node where the player can accept/decline, show the Quest Machine UI that shows all relevant quest info/rewards/buttons
Is this doable without a serious amount of custom scripting? I'm the solo engineer on the project, so I'm not afraid of having to write my own solution or some up with something hacky if necessary, but I'm curious if this is supported out of the box somehow. My off the cuff idea would be to not integrate the two systems and instead fire off scripts to trigger the other system when relevant (i.e pick a quest in the Multiple Quest UI, fire off dialogue system via script, on last node call Quest Machine's method to show the player the Accept/Decline UI). It sounds possible, but kind of gross if there's a better option available.
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Tony Li »

Hi,

Thanks for checking out the Dialogue System and Quest Machine!

These two are easy to do:
Codebread wrote: Sat Apr 04, 2020 7:08 pm
  • If they have multiple quests you see a window that allows you to choose which quest to talk about
Just untick the Dialogue System Quest Dialogue UI component's 'Generate Conversations For Quest Lists' checkbox. It will show Quest Machine's regular quest dialogue UI to let the player select a quest.
Codebread wrote: Sat Apr 04, 2020 7:08 pm
  • The quest offer text is displayed via the Dialogue System, allowing branching conversations, etc
Add a Dialogue System Conversation quest content to the quest's Offer Text, as in the integration's example scene quests. It will automatically show a Dialogue System conversation when the player picks a quest from the list in Quest Machine's quest dialogue UI.
Codebread wrote: Sat Apr 04, 2020 7:08 pm
  • On final node where the player can accept/decline, show the Quest Machine UI that shows all relevant quest info/rewards/buttons
This one's trickier. Once you're in the Dialogue System conversation, there's no built-in way to switch the same quest to Quest Machine's quest dialogue UI. Instead, I recommend making the Dialogue System dialogue UI look similar in design to Quest Machine's quest dialogue UI, and just have Accept and Decline response nodes in the conversation. If you don't want branching conversations' regular response menus to look similar in design to Quest Machine's quest dialogue UI, you can also create an alternate menu panel that you only use for the final Accept/Decline response menu. I can provide more details if you decide to set this up and have any questions.
Codebread
Posts: 8
Joined: Sat Mar 28, 2020 4:16 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Codebread »

Thanks for the quick response!

I should have been more clear - I have the integration working perfectly so I think the first two are taken care of already, I just reiterated in order to describe how I'd like a player's interaction from start to finish to be.

Creating a single Dialogue System menu to work only for the accept/decline state is a really good idea - I'm a little embarrassed I didn't think of it. I'm over-engineering this for sure. I'll give that a shot tomorrow and see if I can get it working. I'm less versed in Dialogue System than I am in Quest Machine (there's so much in Dialogue System!). Is swapping to a separate UI for a single conversation node a simple task?
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Tony Li »

You can use the same dialogue UI.

A dialogue UI consists of subtitle panels and menu panels. Typically there are two subtitle panels (one for NPCs, one for PC) and one menu panel. But you can add a second menu panel specifically for the Accept/Decline node and add it to the dialogue UI's Menu Panels list. Then use the SetMenuPanel() sequencer command to switch menus.

Here's a quick example:

DS_AcceptDeclineMenuExample_2020-04-05.unitypackage

Please also import this patch, which adds some additional convenience functionality to the SetMenuPanel() sequencer command. (Future readers: If you're using DS version 2.2.6 or higher, do not import the patch. It's already included in 2.2.6+.)

DS_SetMenuPanel_Patch_2020-03-27.unitypackage

The example only uses the Dialogue System. The Dialogue Manager's Canvas has a customized version of the Basic Standard Dialogue UI prefab. This dialogue UI is assigned to the Dialogue Manager's Dialogue UI field. I added a second menu panel with 2 pre-positioned response buttons that will be used by the Accept and Decline responses. The conversation node preceding Accept/Decline uses the SetMenuPanel() sequencer command to tell the dialogue UI to use the second menu panel.
Codebread
Posts: 8
Joined: Sat Mar 28, 2020 4:16 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Codebread »

Hey!

A quick update on this:

Firstly, I bought the two packages. I was going to eventually anyway and I wanted access to the source code to see what my limitations are.

Thanks a ton for whipping up that example! I see what you did to make it work, so I'm replicating it to fit our UI. For reference, this is roughly what we're going for (from our previous game):

Image

Instead of creating a Quest Info box that holds all of the information I need from scratch, instead I created a new Lua function, ShowQuestInfo(questGiverID, questID), that is going to display the same Quest Dialogue UI that Quest Machine does, but using a modified version of ShowOfferQuest() to strip the onAccept and onDecline stuff out of it. The Quest Dialogue UI will have to be modified too, but the intent is to use the great functionality that's already there to show all of the quest info, but show/hide it based on which dialogue node is active and using the Accept/Decline in the dialogue to accept/reject the quest.

It's only half done but I think this solution should work without a lot of hassle. And if it doesn't, well, I'll just create a new Quest Info box from scratch to trigger with the dialogue system that takes in a Quest object. No biggie!
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Tony Li »

Sounds good! And thank you for buying the packages. If any other questions come up as you implement this, just let me know. :-)
Codebread
Posts: 8
Joined: Sat Mar 28, 2020 4:16 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Codebread »

Hey Tony, I am actually seeing weird behavior that I can't debug. When using the QuestGiver.StartDialogueWithPlayer(), the menu panel isn't being swapped to the custom panel I made for accepting or declining. It works correctly if I start a conversation with the quest giver using the Dialogue System, however.

It seems like the sequence command is being fired correctly in both cases - they both hit StandardUIResponseMenuControls.OverrideActorMenuPanel(). Does Quest Machine set the menu panel for response nodes that happens after sequences are played in the dialogue system?
Codebread
Posts: 8
Joined: Sat Mar 28, 2020 4:16 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Codebread »

Actually... now that I'm toying around a bit more, maybe using the Dialogue System to start the conversation is best. I'd like to give the player the option to choose between just talking or choosing quests, but the QuestMachine function will jump straight to the quest dialogue.

Would it make sense to structure a conversation like this? :

Options for the player upon speaking to an NPC:

1) Talk -> Leads to normal conversation
2) View Quests -> Displays the quest machine quest list (which subsequently starts a quest conversation when a quest is chosen)
3) Goodbye -> Cancels dialogue

That doesn't really solve the sequencer issue though, since the quest dialogue would still be displayed using the Quest Machine StartDialogue function. I feel like I'm seriously distorting the systems you've created here, am I over-complicating things or do you see people doing stuff like this often?
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using the Quest Machine UIs with the Dialogue System Integration

Post by Tony Li »

Hi,

The Dialogue System Extras page has a patch for SetMenuPanel. Please give it a try. These changes are staged to be in the upcoming version, too. To download the patch, go to the Extras page and expand the "Updated to 2.2.5" foldout.

Here are some ideas for how to start the conversation:

If you start it from the Dialogue System:
  • You can make a response node such as "Do you have any quests for me?" that runs the Quest Giver's StartDialogueWithPlayer() method. To prevent two conversations from running at the same time (since the quest giver would try to start a conversation as the response node was finishing up), set a Dialogue System variable called, say, "ShowQuests". Add another Dialogue System Trigger to the quest giver. Set it to OnConversationEnd. Set the Conditions to require that ShowQuests is true. Add 2 actions: Add Action > Run Lua Code to set ShowQuests false again, and OnExecute() to call the quest giver's StartDialogueWithPlayer().
  • Or, if they're all hand-written quests, you can simply check them all in the conversation and not bother calling QuestGiver.StartDialogueWithPlayer() at all.
If you start it from Quest Machine:
  • Make a subclass of QuestGiver. Override the StartDialogue() method. Check if there are any quests; if not, start a non-quest conversation:

    Code: Select all

    [ConversationPopup] public string myNonQuestConversation = "Conversation Title";
     
    public override void StartDialogue(GameObject player)
    {
        RecordQuestsByState();
        if (activeQuests.Count == 0 && offerableQuests.Count == 0)
        {
            DialogueSystem.StartConversation(myNonQuestConversation, player.transform, this.transform);
        }
        else
        {
            base.StartDialogue(player);
        }
    }
  • Alternatively, if you want to show the quest list right away but also include an option to talk about non-quest stuff, subclass DialogueSystemQuestDialogueUI instead. Override the ShowGeneratedQuestListConversation() method to add another node to go to the non-quest conversation. Roughly:

    Code: Select all

    protected override void ShowGeneratedQuestListConversation(QuestParticipantTextInfo speaker, List<QuestContent> activeQuestsContents, List<Quest> activeQuests, List<QuestContent> offerableQuestsContents, List<Quest> offerableQuests)
    {
        base.ShowGeneratedQuestListConversation(speaker, activeQuestsContents, activeQuests, offerableQuestsContents, offerableQuests);
        // Add extra node:
        var node = template.CreateDialogueEntry(generatedConversation.dialogueEntries.Count, generatedConversation.id, string.Empty);
        node.ActorID = PlayerID;
        node.ConversantID = npcNode.ActorID;
        node.DialogueText = "Let's talk about something other than quests.";
        generatedConversation.dialogueEntries.Add(node);
        // Add link from NPC's greeting to this node:
        var previousNode = generatedConversation.GetDialogueEntry(1);
        var link = new Link(generatedConversation.id, previousNode.id, generatedConversation.id, node.id);
        previousNode.outgoingLinks.Add(link);
        // Add link from this node to some other conversation:
        link = new Link(generatedConversation.id, previousNode.id, SomeOtherConversationID, SomeOtherNodeID);
        node.outgoingLinks.Add(link);
    }
(Note: I'm just typing the code examples in here. There may be typos.)
Post Reply