Get emphasis value via script

Announcements, support questions, and discussion for the Dialogue System.
mac
Posts: 81
Joined: Sat Aug 22, 2020 7:54 pm

Get emphasis value via script

Post by mac »

Hi again Tony, so I'm trying to add an icon that follows every dialogue response, so for example, when a response continues with the dialogue, it would be followed by an exclamation mark icon, optional side chat response would be followed by a chat box icon, responses that would end dialogue would be followed by an 'X' and so on.
I think that the easiest way to 'tag' what each response is would be with the emphasis system, so emphasis 1 would be for the exclamation mark, 2 for the chat box...
But can I access the emphasis value somehow? so I could check for emphasis in a switch statement for example and set my icon according to each emphasis.

I already tried grabbing the response button name as their inspector name shows the color the emphasis applies to them, ( example: a black text inspector name starts with </color>00ff>, so I thought I could do a name.Contain("</color>00ff>") to identify the color and apply the icon) so for that to work I only had to make sure no emphasis had the same exact color, but it seems the string unlike the inspector understand the color, erasing the "</color>00ff>" which the name.Contain would need, so that method does not work.
User avatar
Tony Li
Posts: 21681
Joined: Thu Jul 18, 2013 1:27 pm

Re: Get emphasis value via script

Post by Tony Li »

Hi,

I don't think emphasis tags will be the best fit for this.

What about TextMesh Pro <sprite> tags, assuming you're using TextMesh Pro or willing to switch? For example, you could add <sprite="chat"> to the end of side chat responses.

---

Alternatively, you could add a custom field to the dialogue entry template. If you're up for some scripting, you could even define a custom field type that shows a dropdown menu (exclamation, chat, X, etc.). Then add a script to the Dialogue Manager that has an OnConversationLine method that checks the field and adds the appropriate tag to the text. Example:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    // Assumes you've added a field named "Icon" to the dialogue entry template.
    string icon = Field.LookupValue(subtitle.dialogueEntry.fields, "Icon");
    if (!string.IsNullOrEmpty(icon))
    {
        subtitle.formattedText.text += $"<sprite='{icon}'>";
    }
}
mac
Posts: 81
Joined: Sat Aug 22, 2020 7:54 pm

Re: Get emphasis value via script

Post by mac »

Hmm I'm not sure if textmesh pro would be fitting for what I want to achieve, as you can see in the attached image, the sprite would not exactly follow the text, do you think the second solution would work?
Attachments
Screenshot_5.png
Screenshot_5.png (679.33 KiB) Viewed 1153 times
User avatar
Tony Li
Posts: 21681
Joined: Thu Jul 18, 2013 1:27 pm

Re: Get emphasis value via script

Post by Tony Li »

In that case, maybe do something similar to my second suggestion. I forgot this was for responses, not subtitles, so it will be a bit different.

1. Add a custom field such as "Icon" to the dialogue entry template. For each response node, set it to "Exclamation", "Chat", etc., or blank for no icon.

2. Add all possible icons as children of your response button template.

3. Make a subclass of StandardUIResponseButton. Define variables that can point to those icons. Example:

Code: Select all

public class MyResponseButton : StandardUIResponseButton
{
    public Image exclamation;
    public Image chat; 
    // etc....
}
On your response button template, replace StandardUIResponseButton with your subclass, and assign the variables.

4. Make a subclass of StandardUIMenuPanel that you'll similarly use to replace the class on your menu panel. Override SetResponseButton(). Example:

Code: Select all

public class MyMenuPanel : StandardUIMenuPanel
{
    protected override void SetResponseButton(StandardUIResponseButton button, Response response, Transform target, int buttonNumber)
    {
        base.SetResponseButton(button, response, target, buttonNumber);
        
        // Enable the right icon for this response:
        string icon = Field.LookupValue(response.destinationEntry.fields, "Icon");
        var myButton = button as MyResponseButton;
        myButton.exclamation.enabled = (icon == "Exclamation");
        myButton.chat.enabled = (icon == "Chat");
        // etc....
    }
}
mac
Posts: 81
Joined: Sat Aug 22, 2020 7:54 pm

Re: Get emphasis value via script

Post by mac »

Alright I got a bit lost on the first step, the field displayed on the attached image is where I should set the custom field, but should I have one for each type of icon? What type should I set it? Does value stay empty?
Attachments
Screenshot_1.png
Screenshot_1.png (35.98 KiB) Viewed 1148 times
User avatar
Tony Li
Posts: 21681
Joined: Thu Jul 18, 2013 1:27 pm

Re: Get emphasis value via script

Post by Tony Li »

Hi,

Here's an example:

DS_TweenResponseButtonExample_2021-04-10.unitypackage

I added a custom field type called "Icon Type". I used the template in Templates/Scripts/Editor and filled in the code where the commented indicated.
CustomFieldType_IconType.cs

Code: Select all

using UnityEngine;
using UnityEditor;
using System;

namespace PixelCrushers.DialogueSystem
{

    public enum IconType
    {
        None,
        Regular,
        Side,
        Final
    }

    /// <summary>
    /// This example class adds a custom field type named "Icon" that lets you choose
    /// from a list of icon types.
    /// </summary>
    [CustomFieldTypeService.Name("Icon Type")]
    public class CustomFieldType_IconType : CustomFieldType
    {

        public override string Draw(string currentValue, DialogueDatabase database)
        {
            var enumValue = GetCurrentIconType(currentValue);
            return EditorGUILayout.EnumPopup(enumValue).ToString();
        }

        public override string Draw(Rect rect, string currentValue, DialogueDatabase database)
        {
            var enumValue = GetCurrentIconType(currentValue);
            return EditorGUI.EnumPopup(rect, enumValue).ToString();
        }

        private IconType GetCurrentIconType(string currentValue)
        {
            if (string.IsNullOrEmpty(currentValue)) currentValue = IconType.None.ToString();
            try
            {
                return (IconType)Enum.Parse(typeof(IconType), currentValue, true);
            }
            catch (Exception)
            {
                return IconType.None;
            }
        }

    }
}
Then I added an "Icon" field to the dialogue entry template and selected Menu > Apply Template To Asset to add the field to existing dialogue entry nodes. The checkbox makes the field appear in the node's main inspector area; otherwise you'd have to expand All Fields to see it.

iconInTemplate.png
iconInTemplate.png (55.89 KiB) Viewed 1147 times

I used these scripts to show the icons:
IconResponseButton.cs

Code: Select all

using UnityEngine.UI;
using PixelCrushers.DialogueSystem;

public class IconResponseButton : StandardUIResponseButton
{
    // Icons for the different response types.
    // IconMenuPanel.SetResponseButton will activate the appropriate one.
    public Image regular;
    public Image side;
    public Image final;
}
IconMenuPanel .cs

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class IconMenuPanel : StandardUIMenuPanel
{
    // Looks up the response's icon type and activates the corresponding icon image.
    protected override void SetResponseButton(StandardUIResponseButton button, Response response, Transform target, int buttonNumber)
    {
        base.SetResponseButton(button, response, target, buttonNumber);

        // Enable the right icon for this response:
        var myButton = button as IconResponseButton;
        if (myButton != null)
        {
            string icon = Field.LookupValue(response.destinationEntry.fields, "Icon");
            myButton.regular.enabled = (icon == "Regular");
            myButton.side.enabled = (icon == "Side");
            myButton.final.enabled = (icon == "Final");
        }
    }
}
mac
Posts: 81
Joined: Sat Aug 22, 2020 7:54 pm

Re: Get emphasis value via script

Post by mac »

Awesome, it works perfectly Tony, you're the man, here how it looks:
Attachments
Screenshot_1 (1).png
Screenshot_1 (1).png (331.01 KiB) Viewed 1142 times
User avatar
Tony Li
Posts: 21681
Joined: Thu Jul 18, 2013 1:27 pm

Re: Get emphasis value via script

Post by Tony Li »

Looks good!
mac
Posts: 81
Joined: Sat Aug 22, 2020 7:54 pm

Re: Get emphasis value via script

Post by mac »

There is a small problem I noticed a while ago (way back before any big change), the player never unfocus while NPC is talking, only thing that happens is the NPC blinks, and then he goes back to focused, but player stays unaffected. Any idea why? Added a video to drive displaying the behavior:
User avatar
Tony Li
Posts: 21681
Joined: Thu Jul 18, 2013 1:27 pm

Re: Get emphasis value via script

Post by Tony Li »

Hi,

Can you back up your project and import the dialogue UI update for version 2.2.15 available on the Dialogue System Extras page? Or, better yet, update to version 2.2.16. It should be available on the Asset Store in the next few days.
Post Reply