Page 1 of 3

How to format & disable responses based on variables/quest states?

Posted: Sat Sep 02, 2017 8:18 pm
by Abelius
Hi,

This could go far beyond the expected use of DS but, I need to ask in case there's a not too complex way to achieve it.

I need some responses grayed out and disabled, but only if a given stat (number variable) is not high enough at that moment. That is, the response should be visible but not clickable, as a way of 'teasing' the player that if s/he returns with an upgraded stat, then that response will be enabled.

Is this possible?

The only alternative (and convoluted) way I've thought of is to use cloned non-interactable UI buttons with a grayed out font, and send a PlayMaker event at the end of the previous conversation node to fill them with the same text as their 'real' responses have. And then use a variable conditional to block them as appropriate.

So if the response is available in the 'real' UI, you could click it, and if it's not then the 'fake' response would be there as well...

Well, it could work but... something more automated would be awesome. :P

Thanks for your time.

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 03, 2017 12:36 am
by Tony Li
Hi,

There are two parts to this.

The first part is to use the Conditions field to check whether a response is enabled or disabled. For example, let's say you record your player's Agility score in a dialogue database variable named "Agility". You could define a response like this:
  • Menu Text: [Pick Lock (requires agility 50+)]
  • Conditions: Variable["Agility"] >= 50
The second part is to selectively show only certain invalid responses. (Disabled responses are called "invalid" in the Dialogue System.) If you're okay with showing all invalid responses, you can do step #1 below (tick Input Settings > Include Invalid Entries) and that's it. You're done.

However, if you only want to show specific invalid responses and leave the other invalid responses hidden, you can make a subclass of UnityUIDialogueUI and override the ShowResponses method. If you're not into coding, no worries! Here's an example scene and script:

ShowInvalidResponsesExample_2017-08-19.unitypackage

In case you're not using Unity 5.6.0 or higher, I'll also include the script at the bottom of this reply.

Here's how I set up the scene:

1. Inspected the Dialogue Manager and ticked Input Settings > Include Invalid Entries. Also, make sure your response button's Disabled state uses some distinguishing color such as a gray at 50% alpha. (If you want to show all invalid responses, you can stop here.)

2. Replaced the Unity UI Dialogue UI component with Unity UI Dialogue UI Show Invalid Responses. To do this, I changed the Inspector to Debug mode using the three-bar menu in the top right of the Inspector. Then I dragged UnityUIDialogueUIShowInvalidResponses.cs onto the Script field, replacing UnityUIDialogueUI. This replaced the script while keeping all the UI element assignments intact. Then I switched the Inspector back to Normal mode using the three-bar menu:

Image

3. Added a new custom field named "Show Invalid" (Boolean type) to the Dialogue Entries template:

Image

4. Ticked the "Main" checkbox to show it in the main part of the Dialogue Entry inspector so I won't have to dig into the "All Fields" foldout:

Image

For invalid entries that you still want to show in the response menu, simply set "Show Invalid" to True.



UnityUIDialogueUIShowInvalidResponses.cs

Code: Select all

using UnityEngine;
using System.Collections.Generic;
using PixelCrushers.DialogueSystem;

public class UnityUIDialogueUIShowInvalidResponses : UnityUIDialogueUI
{

    public string showInvalidFieldName = "Show Invalid";

    public override void ShowResponses(Subtitle subtitle, Response[] responses, float timeout)
    {
        responses = CheckInvalidResponses(responses);
        base.ShowResponses(subtitle, responses, timeout);
    }

    private Response[] CheckInvalidResponses(Response[] responses)
    {
        if (!HasAnyInvalid(responses)) return responses;
        var list = new List<Response>();
        for (int i = 0; i < responses.Length; i++)
        {
            var response = responses[i];
            if (response.enabled || Field.LookupBool(response.destinationEntry.fields, showInvalidFieldName))
            {
                list.Add(response);
            }
        }
        return list.ToArray();
    }

    private bool HasAnyInvalid(Response[] responses)
    {
        if (responses == null) return false;
        for (int i = 0; i < responses.Length; i++)
        {
            if (!responses[i].enabled) return true;
        }
        return false;
    }

}

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 03, 2017 9:16 am
by Abelius
Wow Tony, what an awesome reply! :mrgreen:

I should have specified that I only need ALL invalid responses to be inactive, so you didn't need to explain the whole thing.

Oh, and I also should have said I'm using a modified 'Wheel2' response panel because I still need a little more functionality... it seems. :?

I mean, the invalid response is showing and its associated button is disabled indeed. That works and it's great! Also, those buttons use sprite switching, so I only need to ask my artist to give me gray-tinted versions to assign them to the 'disabled' state sprites.

But I don't feel it is enough for this 'Wheel' response panel, because players will focus on the text instead of the little wheel sprites. In fact, they need to hover the text to select a response, not the button.

This is how it looks...:

Image

When you hover on the first response (valid), this happens:

Image

The button sprite switches to its highlighted version and the associated label text changes its color thanks to these built in components:

Image

That's perfect, but then there's that second response... it's also in its default color white, you see. That's the normal behavior of Unity UI Text components, of course. It doesn't have a 'set this color when my parent button is disabled' field.

So I'd need to add a watcher FSM to each label, that changes its text color to gray when its parent button is disabled. But the problem I foresee is that those previous scripts will still do this...:

Image

...even though the button is disabled. :|

I obviously don't want the text highlighted when a response is invalid.

So... what about adding a 'Em Tag For Invalid Responses' field here...? :roll:

Image

I guess that if I'd use Em 1 for those, they'd always be grayed out when invalid. And when they're clickable for the first time they'd be white... and when they've been already been selected they'd show formatted as Em 4 says, right?

That would be perfect... :P

Thanks!

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 03, 2017 11:17 am
by Tony Li
Good idea! I'll be working on Dialogue System updates this upcoming week. I'll add that dropdown!

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 03, 2017 2:44 pm
by Abelius
Haha! If I continue adding items to that shopping list, I'll feel bad about having paid DS only once! :lol:

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 03, 2017 3:22 pm
by Tony Li
Not at all! Sometimes I feel like I should be paying you all when you come up with good ideas to improve the Dialogue System. :)

Re: How to format & disable responses based on variables/quest states?

Posted: Sun Sep 17, 2017 6:01 pm
by Abelius
Hi Tony,

I was just wondering how you're seeing the business of adding that dropdown list field. It's the feature which I need to most for development, but no pressures here, ofc. Just asking. ;)

Thanks!

Re: How to format & disable responses based on variables/quest states?

Posted: Mon Sep 18, 2017 12:14 am
by Tony Li
Hi,

The dropdown field is in patch 20170917, which is available on the Pixel Crushers private customer download site. If you don't have access, please PM me your invoice number and I'll set it up.

Re: How to format & disable responses based on variables/quest states?

Posted: Mon Sep 18, 2017 3:25 am
by Abelius
Sent!

Thank you! ;)

Re: How to format & disable responses based on variables/quest states?

Posted: Sat Nov 04, 2017 8:41 am
by Abelius
Hi Tony,

I never got to thank you for releasing 1.7.6 with all those new features I asked of you. Life's been a little hectic and only recently I've returned to Dialogue System tasks in my game. ;)

So, I've tried this feature for the invalid responses being colored with a specific Em tag and, although it works, I have a special use case that it is giving me a little problem.

You see, I'm already tagging those variable-conditioned responses with a pink-colored Em3 tag, while the invalid response tag is colored in a darker tone of red (Em1). And that manually set Em tag seems to take precedence over the invalid response tag.

What I'd like is that if the response is declared valid (the condition is met), then it's colored in pink (Em3). And if the response is declared invalid, the Em1 dark red tag kicks in and it takes precedence over the manually set Em3 pink tag.

This way, the player will always see that response as dark red and unclickable until he gains enough points and the response turns pink and he can finally select it for the first time. Oh, and that also would mean that when the player chooses this response a second time, the 'old responses' Em tag would be used and colored in gray (in my case), right? That also would be nice in my books as well.

Now, I understand this approach of mine could be undesirable for other people so, could some setting be put under the Em tag dropdown lists? So that behavior could be toggled on/off? Maybe even on a per Em tag basis? I mean, one on/off setting for 'old responses' and another for 'invalid responses'? So all use scenarios are covered.

Thank you!