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 (19.41 KiB) Viewed 879 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.)