Page 1 of 1

Setting sprite image by name instead of number [img=#]

Posted: Fri Jan 07, 2022 6:18 am
by YBusbach
Hi there,

I recently bought DS to use in a very dialog heavy game and it's made our work a ton easier!
We're using a VN style dialog system with the Player and NPCs using various sprites to express their emotions.

From the manual I learned that I can use [pic=#] to change which sprite is being used for a character, but I was wondering if there is an alternate way to to do it that could use the suffix of the sprite instead.

For example, all our sprites are named by their emotional state as follows:
charactername_angry
charactername_sad
etc.

Would it be possible to set up so that we can use their suffix (e.g. [pic=angry]) rather than than having to remember the numbers for each sprite? ([pic=15])

Thanks for your help! :)

Re: Setting sprite image by name instead of number [img=#]

Posted: Fri Jan 07, 2022 11:03 am
by Tony Li
Hi,

There are several ways to accomplish this. I'll describe a few so you can pick one that works best for your workflow.

Three ways to change portraits are:
If you put your sprite images in a Resources folder or asset bundle, or mark them as Addressable using the Addressables package, then you can use image names with the SetPortrait() sequencer command in the dialogue entry node's Sequence field. Example:
  • Sequence: {{default}}; SetPortrait(Adam, angry)
(The {{default}} keyword tells the sequence to also play the Dialogue Manager's Default Sequence.)

---

If you want to continue with [pic=#] tags, you can take advantage of the fact that [var=variable] tags are processed before [pic=#] tags. There are many ways to do this. Let's say all of your actors use:
  • pic 1 = default
  • pic 2 = happy
  • pic 3 = sad
  • pic 4= angry
Then you could set DS variables like this:

happySadAngry.png
happySadAngry.png (19.41 KiB) Viewed 579 times

In place of Dialogue Text like "I'm angry! [pic=4]", you'd use "I'm angry! [var=angry]".

---

Another alternative is to add a script with an OnConversationLine special method to the Dialogue Manager GameObject and process your own custom tags in the text. Example:

Code: Select all

using System.Text.RegularExpressions;
using UnityEngine;
using PixelCrushers.DialogueSystem;

public class ProcessImgTags : MonoBehaviour
{
    void OnConversationLine(Subtitle subtitle)
    {
        // Process custom [img=imageName] tags:
        var match = Regex.Match(subtitle.formattedText.text, @"\[img=(^\])+\]");
        if (match.Success)
        {
            // Get the image name from [img=imageName]:
            var imageName = match.Value.Substring(5, match.Value.Length - 6).Trim();

            // Remove the tag from the text:
            subtitle.formattedText.text = subtitle.formattedText.text.Remove(match.Index, match.Length);

            var actor = DialogueManager.masterDatabase.GetActor(subtitle.speakerInfo.id);
            if (actor != null)
            {
                // Find the corresponding pic:
                if (actor.spritePortrait != null && actor.spritePortrait.name == imageName)
                {
                    subtitle.formattedText.pic = 1;
                }
                else
                {
                    for (int i = 0; i < actor.alternatePortraits.Count; i++)
                    {
                        if (actor.alternatePortraits[i] != null && actor.alternatePortraits[i].name == imageName)
                        {
                            subtitle.formattedText.pic = i + 2;
                            break;
                        }
                    }
                }
            }
        }
    }
}
(Note: I typed that script into the reply; it might have typos.)

Re: Setting sprite image by name instead of number [img=#]

Posted: Mon Jan 10, 2022 4:34 am
by YBusbach
Thanks for the detailed reply Tony!

I'll be testing out your suggested methods and I think defining variables will likely be the easiest solution for our team. :mrgreen: