Interrupting Conversation Occasionally

Announcements, support questions, and discussion for the Dialogue System.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Interrupting Conversation Occasionally

Post by Mackerel_Sky »

Hi,

I've implemented a system to allow the player to discard an item they picked up or something in their inventory, if they pick it up while their inventory is full. The choice is made through the Dialogue System.

Sometimes, the player is rewarded with items from a quest. In these cases, I use the sequencer to run the same function that I use to give the player items outside of a conversation-normally this will run the check and start the Inventory Full dialogue, but it seems like this doesn't trigger in my project since I'm already in the middle of another conversation- so I need to figure out how to check if the inventory is full before adding the item in, and then interrupt the conversation to allow the player to make the choice. Then I need to return to the original conversation. The function should only trigger after the dialogue node finishes- e.g. the flow would be "You Got 1 Apple." > CheckInventory().

Somebody seems to have had a similar problem to me earlier and asked on the forum- the link is here. https://www.pixelcrushers.com/phpbb/vie ... upt#p13358

The solution seems easily implemented, but I need to figure out how to know when to do so. Do you have any ideas? Just writing about it seemed to make it a bit clearer but I'm still not 100% as to how I would approach this.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Interrupting Conversation Occasionally

Post by Tony Li »

Hi,

The conversation position stack should work for this. Use PushConversationPosition() in the node where the NPC says "Here's your reward.". Put an empty node next, with the Sequence set to Continue(). This delays evaluation of the inventory full check. Here's an example:

pushPop.png
pushPop.png (24.67 KiB) Viewed 1051 times

Set the Conditions for "Enjoy your reward!" to check if the player has room.

Set the Conditions for "Oh, your hands are full." to check if the player's inventory is full. If so, link to the "drop item" conversation. In the last node of the "drop item" conversation, use PopConversationPosition(). This will return the conversation to "Here's your reward.". If you run the "drop item" conversation on its own (e.g., when picking up an item during gameplay), the PopConversationPosition() will log a warning in the Console, but it's otherwise harmless.

An alternative would be to pause the conversation and open the player's inventory UI and a separate item container UI if the player's inventory is full. Then the player can choose to drop an item from the inventory UI and drag the quest reward item from the item container UI into the newly-opened slot in the inventory UI.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Interrupting Conversation Occasionally

Post by Mackerel_Sky »

Hey Tony,

Thanks for your response. Couple of clarifications-

- Is it possible to push the 'Enjoy your reward' conversation instead of the original choice? It would be a bit weird to loop through the starting conversation after finishing the inventory choice.

- Should I be calling ClearConversationPositionStack() anywhere? If I don't, and trigger the inventory choice later on, wouldn't the Pop function get called and return to the NPC's conversation?

Thanks
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Interrupting Conversation Occasionally

Post by Tony Li »

Hi,

Here's an example scene:

DS_PushPopInventoryExample_2020-03-24.unitypackage
Mackerel_Sky wrote: Tue Mar 24, 2020 7:05 am- Is it possible to push the 'Enjoy your reward' conversation instead of the original choice? It would be a bit weird to loop through the starting conversation after finishing the inventory choice.
No. You can only push the node that you're currently showing. But you can push an empty node and return to that node, as in the example above.
Mackerel_Sky wrote: Tue Mar 24, 2020 7:05 amShould I be calling ClearConversationPositionStack() anywhere? If I don't, and trigger the inventory choice later on, wouldn't the Pop function get called and return to the NPC's conversation?
You can. But by default the stack is cleared when the conversation ends.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Interrupting Conversation Occasionally

Post by Mackerel_Sky »

Hi Tony,

The example matched what I needed perfectly. I think I understand the concept behind it now!

Thanks for your help!
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Interrupting Conversation Occasionally

Post by Tony Li »

Glad to help! :-)
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Interrupting Conversation Occasionally

Post by Mackerel_Sky »

Hey Tony,

I spent the last few days bogged down in work and finishing off the non-DS code for overflowing my inventory so I couldn't get around to implementing your solution until now. For some reason I'm getting a error for

Code: Select all

Dialogue System: Lua code 'PushConversationPosition()' threw exception 'Tried to invoke a function call on a non-function value. If you're calling a function, is it registered with Lua?'
It's a built-in function so I don't need to register it, right? I don't think you did in your example so I think I must have gone wrong somewhere else.

Thanks!
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Interrupting Conversation Occasionally

Post by Tony Li »

Hi,

Please add a Conversation Position Stack component to your Dialogue Manager. The position stack Lua functions are optional functions that are only available if you add this component.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Interrupting Conversation Occasionally

Post by Mackerel_Sky »

Hey Tony,

That fixed it- thanks for your help. I haven't started working on this next part yet but I hope to implement it soon.

The situation is that each time the player is given something from a conversation e.g. "Make some coffee?" they run the inventory full check as you provided. If they can successfully add the item, they go to a node like "Made some coffee." If their inventory is full, they get something like "Your bag is full." and go to the inventory management conversation.

This conversation will allow the player to discard the item they just got, which calls PopConversationPosition to return to the check. I fiddle with a couple of variables to play some discard node dialogue like "You poured the coffee on the floor". The alternative is that they can open the inventory to delete enough items to make room for the new item, which needs to close the conversation window.

In the inventory, there are buttons to discard the item as well if the player changes their mind. I need to return to the check position when the player finishes dealing with the inventory to run the discard node again if they chose to discard the item, or success node if they added it in. It might be simpler to just go to the node directly as well. Is there functionality to just start a conversation at a certain node in DS?

If not, I think I can handle it by creating some more variables and conditional links from start to the discard/success nodes but I want to keep it as clean as possible.

Thanks!

EDIT:

I think I found the correct documentation on the manual- StartConversation with a initial DialogueEntryID. Is this correct? Then the problem becomes one of getting the correct conversationID and storing it in a variable somewhere.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Interrupting Conversation Occasionally

Post by Tony Li »

Yup! You found it.

In C# code, you can use DialogueManager.StartConversation with an entry ID. Or you can configure a Dialogue System Trigger to start at a specific entry (or equivalent for visual scripting, Timeline, etc.).

To record the current conversation ID, add an OnConversationLine method and/or check DialogueManager.currentConversationState. Example:

Code: Select all

int currentConversationID;

void OnConversationLine(Subtitle subtitle)
{
    currentConversationID = subtitle.dialogueEntry.conversationID;
}
(Alternatively, you could record it once in OnConversationStart and then re-record it if necessary in OnLinkedConversationStart.)
Post Reply