[HOWTO] How To: Prepend actor name and indent in TextMesh Pro

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
User avatar
Tony Li
Posts: 22118
Joined: Thu Jul 18, 2013 1:27 pm

[HOWTO] How To: Prepend actor name and indent in TextMesh Pro

Post by Tony Li »

This script, added to the Dialogue Manager, does the following:
  • Prepends the speaker's name -- but not on subsequent lines spoken by the same speaker, until a different speaker speaks.
  • Applies color to the speaker's name if the speaker has a Dialogue Actor component. (Tick Set Subtitle Color, set the color, then UNtick Set Subtitle Color.)
  • Indents text 20%. Requires TextMesh Pro, and works best with the latest versions of TextMesh Pro as there are indent issues with earlier versions. NOTE: And with later versions, as Unity keeps reintroducing this bug. You can apply the fix described in this post. See also: How can I modify built-in packages?
PrependNamesAndIndent.cs

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

/// <summary>
/// Prepends speaker's name to first dialogue line but not subsequent lines
/// until switching to a new speaker. Also indents using TMPro tags and 
/// applies Dialogue Actor color to name.
/// 
/// NOTE: You *MUST* untick Dialogue Actor's Set Subtitle Color so Dialogue
/// Actor doesn't itself prepend actor name with color.
/// </summary>
public class PrependNamesAndIndent : MonoBehaviour
{
    private string currentName;

    void OnConversationStart(Transform actor)
    {
        currentName = string.Empty;
    }

    void OnConversationLine(Subtitle subtitle)
    {
        if (!string.IsNullOrEmpty(subtitle.formattedText.text))
        {
            // Indent:
            var text = subtitle.formattedText.text;
            text = $"<indent=20%>{text}</indent>";

            // If a new speaker, prepend the name:
            if (subtitle.speakerInfo.Name != currentName)
            {
                currentName = subtitle.speakerInfo.Name;
                var dialogueActor = DialogueActor.GetDialogueActorComponent(subtitle.speakerInfo.transform);
                if (dialogueActor != null)
                {
                    // Apply Dialogue Actor color to name:
                    var webcolor = Tools.ToWebColor(dialogueActor.standardDialogueUISettings.subtitleColor);
                    text = $"<color={webcolor}>{currentName}</color> - {text}";
                }
                else
                {
                    text = $"{currentName} - {text}";
                }
            }
            subtitle.formattedText.text = text;
        }
    }
}
Post Reply