[HOWTO] How To: Color Actor Name and Indent Text
Posted: Wed Apr 03, 2024 3:07 pm
This script is a replacement for StandardUISubtitlePanel. It does the following:
- Prepends the speaker's name using the actor's Node Color as set in the Dialogue Editor window. (You must set the actor's Node Color.)
- Indents the text after the actor's name.
- Combines sequential lines spoken by the same actor into the same paragraph instead of separating them with a newline.
- Sets older lines' alpha color values to semitransparent.
Code: Select all
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class ContinueParagraphSubtitlePanel : StandardUISubtitlePanel
{
private int previousSpeakerID;
private bool firstChange;
private string originalWebColor;
public override void OnConversationStart(Transform actor)
{
base.OnConversationStart(actor);
previousSpeakerID = -1;
addSpeakerName = false; // We'll do it manually.
firstChange = true;
}
protected override void Awake()
{
base.Awake();
originalWebColor = Tools.ToWebColor(subtitleText.color);
}
protected override void SetSubtitleTextContent(Subtitle subtitle)
{
// Change old text <color=#rrggbbff> tags to alpha aa: // Change "aa" to a lower hex number if you want darker.
accumulatedText = accumulatedText.Replace("ff>", "aa>");
if (subtitle.speakerInfo.id != previousSpeakerID &&
!string.IsNullOrEmpty(subtitle.formattedText.text))
{
// This is a new speaker, so prepend actor name and indent:
// Prepend actor name with color:
var actor = DialogueManager.masterDatabase.GetActor(subtitle.speakerInfo.id);
if (actor != null)
{
var nodeColor = DialogueLua.GetActorField(actor.Name, "NodeColor").asString;
if (!string.IsNullOrEmpty(nodeColor))
{
var richTextColor = Tools.ToWebColor(NodeColorStringToColor(nodeColor));
var closeIndent = (previousSpeakerID != -1) ? "</indent>\n" : (firstChange && previousSpeakerID != -1 ? "\n" : "");
if (previousSpeakerID != -1 && firstChange)
{
closeIndent += "\n";
firstChange = false;
}
subtitle.formattedText.text = $"{closeIndent}<color={richTextColor}>{subtitle.speakerInfo.Name}: </color><color={originalWebColor}><indent=10%> {subtitle.formattedText.text}</color>";
}
}
base.SetSubtitleTextContent(subtitle);
}
else
{
// If the same speaker, add to paragraph.
// This code is similar to the base SetContent() except it doesn't
// add a line break.
TypewriterUtility.StopTyping(subtitleText);
var previousText = accumulateText ? accumulatedText : string.Empty;
subtitle.formattedText.text = $"<color={originalWebColor}>{subtitle.formattedText.text}</color>";
if (accumulateText && !string.IsNullOrEmpty(subtitle.formattedText.text))
{
if (numAccumulatedLines < maxLines)
{
numAccumulatedLines += (1 + NumCharOccurrences('\n', subtitle.formattedText.text));
}
else
{
// If we're at the max number of lines, remove the first line from the accumulated text:
previousText = RemoveFirstLine(previousText);
}
}
var previousChars = accumulateText ? UITools.StripRPGMakerCodes(Tools.StripTextMeshProTags(Tools.StripRichTextCodes(previousText))).Length : 0;
SetFormattedText(subtitleText, previousText, subtitle);
if (accumulateText) accumulatedText = UITools.StripRPGMakerCodes(subtitleText.text);
if (scrollbarEnabler != null && !HasTypewriter())
{
scrollbarEnabler.CheckScrollbarWithResetValue(0);
}
else if (delayTypewriterUntilOpen && !hasFocus)
{
DialogueManager.instance.StartCoroutine(StartTypingWhenFocused(subtitleText, subtitleText.text, previousChars));
}
else
{
TypewriterUtility.StartTyping(subtitleText, subtitleText.text, previousChars);
}
}
previousSpeakerID = subtitle.speakerInfo.id;
}
public static Color NodeColor_Orange = new Color(1f, 0.5f, 0);
public static Color NodeColor_Gray = new Color(0.9f, 0.9f, 0.9f);
public static Color NodeColor_Blue = new Color(0.4f, 0.6f, 1f);
public static Color NodeColor_Green = new Color(0, 1f, 0);
public static Color NodeColor_Red = new Color(1f, 0.1f, 0.1f);
private Color NodeColorStringToColor(string s)
{
switch (s)
{
case "Aqua":
return Color.cyan;
case "Blue":
return NodeColor_Blue;
case "Gray":
return NodeColor_Gray;
case "Green":
return NodeColor_Green;
case "Grey":
return Color.gray;
case "Orange":
return NodeColor_Orange;
case "Red":
return NodeColor_Red;
case "Yellow":
return Color.yellow;
default:
return Tools.WebColor(s);
}
}
}