Disabling response button if that button was pressed before

Announcements, support questions, and discussion for the Dialogue System.
nishant
Posts: 55
Joined: Mon Sep 21, 2015 3:16 pm
Location: Canada
Contact:

Disabling response button if that button was pressed before

Post by nishant »

Hi ,
I have a conversation which has a loop inside it and that loop involves set of responses. What I want is that if user clicks a particular response button and later comes back to same set of options, the previously selected option must be disabled and greyed out in some way. How do I achieve this ??
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: Disabling response button if that button was pressed before

Post by Tony Li »

Hi Nishant,

1. On your Dialogue Manager, tick Include Sim Status. This will record the status of every dialogue entry. The status may be:
  • Untouched: Was never shown in a response menu or spoken by an NPC.
  • WasOffered: Was shown in a response menu but not clicked.
  • WasDisplayed: Was clicked in a response menu or spoken by an NPC.
2. On the Dialogue Manager, set Input Settings > Em Tag For Old Responses to one of the Em values, such as Em 1.

3. In your dialogue database, on the Database tab, expand Emphasis Settings and set Emphasis 1 to the greyed out color you want to use.

At this point, already-clicked responses will appear in grey. Now you need to also disable those responses:

5. Create a subclass of your dialogue UI, such as UnityUIDialogueUI. Override the ShowResponses method to disable those responses. Let's say your dialogue UI uses Button Template and Button Template Holder, like the Generic Unity UI Dialogue UI does. Use a class like this:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class MyDialogueUI : UnityUIDialogueUI {

    public override void ShowResponses(Subtitle subtitle, Response[] responses, float timeout) {
        // Set up the buttons as normal:
        base.ShowResponses(subtitle, responses, timeout);
        
        // Then disable the buttons for already-clicked responses:
        foreach (var buttonObject in dialogue.responseMenu.instantiatedButtons) {
            var responseButton = buttonObject.GetComponent<UnityUIResponseButton>();
            var entry = responseButton.response.destinationEntry;
            var alreadyClicked = Lua.IsTrue("Dialog[" + entry.id + "].SimStatus == 'WasDisplayed'");
            responseButton.button.interactable = !alreadyClicked;
        }
    }
} 
Then drag this script into the Script field of your dialogue UI component to replace UnityUIDialogueUI.
nishant
Posts: 55
Joined: Mon Sep 21, 2015 3:16 pm
Location: Canada
Contact:

Re: Disabling response button if that button was pressed before

Post by nishant »

Hello ,
I was able to grey used repsonses but not able to disable them. Did a bit of debugging and it turns out alreadyClicked is always returned as false and yes I did double check if I ticked include sim status. I also checked if it returns true for other SimStatus (Untouched, WasOffered), but it returns false everytime. Anything else that should be done here ??

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

Re: Disabling response button if that button was pressed before

Post by Tony Li »

Hi Nishant,

Maybe there's a typo in your Lua command.

Here's an example: DisableOldResponsesExample_2015-11-12.unitypackage (updated)

I copy-pasted the entire script from my previous post above. It imports into Test/DisableOldResponses. When you play the scene, talk to Private Hart. After your first response, press Escape to cancel the conversation. Then talk to Private Hart again. You'll see that the response you chose is colored red, which is the default setting for em1.

I also left a Lua Console component on the Dialogue Manager. While you're in a conversation, press ~+L to open the console. Then you can type Lua commands such as:

Code: Select all

return Dialog[1].SimStatus
where 1 is the ID of the dialogue entry node. The Dialog array is only valid during conversations. When you're not in a conversation, you have to specify the conversation ID, such as:

Code: Select all

return Conversation[1].Dialog[1].SimStatus
nishant
Posts: 55
Joined: Mon Sep 21, 2015 3:16 pm
Location: Canada
Contact:

Re: Disabling response button if that button was pressed before

Post by nishant »

Hi Tony ,
I tried your test scene. It has the same behavior. Although the color of previously clicked responses change but I am still able to click them
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: Disabling response button if that button was pressed before

Post by Tony Li »

I'll double check and reply back soon.
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: Disabling response button if that button was pressed before

Post by Tony Li »

Sorry, there was a mistake in the Lua.IsTrue line. Lua.IsTrue expects a condition, such as "1+1 == 2", not a return statement such as "return (1+1 == 2)".

I fixed it in the code above, and also in this version of the package:

DisableOldResponsesExample_2015-11-12.unitypackage
nishant
Posts: 55
Joined: Mon Sep 21, 2015 3:16 pm
Location: Canada
Contact:

Re: Disabling response button if that button was pressed before

Post by nishant »

that solves it :)
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Disabling response button if that button was pressed before

Post by VoodooDetective »

Is there any way to only record the sim status for dialogue options? I'm not 100% sure, but the code seems like it currently records every single node in every conversation. Or maybe i'm wrong?

It seems like we should only care about the nodes which represent dialogue options for the Menu Panel. Sorry if I'm missing that part :/ Been a long day.

Also, is it possible to change the name of the conversation table so that it's something shorter like "C". For me that change saves ~20% of the save file
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: Disabling response button if that button was pressed before

Post by Tony Li »

It saves every node. When using SimStatus, it's common to check if a non-dialogue option node has been shown -- for example, if its conditions were true at some point and the conversation chose to follow its branch.

Do you need to save everything in the conversation tables? If not, untick Include All Conversation Fields. SimStatus is saved in a much more compact format if you've unticked All Conversation Fields. If you need to save specific additional fields in conversations, you can write a custom saver or assign a method to PersistentDataManager.GetCustomSaveData.

Side note: A large, successful game that uses the Dialogue System and has a LOT of dialogue (all combat, skill checks, everything, is in dialogue) uses SimStatus. They opted to use the 'Save Raw Data' option which generates even larger save data but works much faster. If I recall, it's fast enough that they stopped using PersistentDataManager's async save mode. They do the data storage part async, though, of course.
Post Reply