I believe when the dialogue buffer gets too long, it starts causing slowdown issues for new dialogue. Like not scrolling all the way to the new text and an temporary fps drop when clicking continue.
Is there a way to set a max buffer? Or in other words, a point in which the dialogue stops being saved in the scrollback?
Yes, there is. How is your dialogue UI configured?
If you're using the Textline template or SMSDialogueUI component, set Max Messages to a non-zero value such as 20 or 50.
If you're using the StandardUISubtitlePanel component's Accumulate Text checkbox, you can trim the top of the buffer by adding a small script to the dialogue UI:
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class TrimSubtitleText : MonoBehaviour
{
public int maxAccumulatedCharacters = 1000;
void OnConversationLine(Subtitle subtitle)
{
var subtitlePanel = (DialogueManager.dialogueUI as StandardDialogueUI).conversationUIElements.defaultNPCSubtitlePanel;
var accumulatedText = subtitlePanel.accumulatedText;
if (accumulatedText.Length > maxAccumulatedCharacters)
{
accumulatedText = accumulatedText.Substring(accumulatedText.Length - maxAccumulatedCharacters);
}
}
}
using UnityEngine;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using PixelCrushers.DialogueSystem;
public class TrimAndGrayPreviousTextSubtitlePanel : StandardUISubtitlePanel
{
// Only keep this many lines in the subtitle panel:
protected const int maxLines = 100;
protected const string grayOpenTag = "<color=#c0c0c0>";
protected const string grayCloseTag = "</color>";
protected const string pattern = @"<color=\w+>|<color=[#][\w|\d]+>|</color>";
public List<string> previousLinesWithoutColor = new List<string>();
public override void OnConversationStart(Transform actor)
{
base.OnConversationStart(actor);
previousLinesWithoutColor.Clear();
}
public override void SetContent(Subtitle subtitle)
{
if (previousLinesWithoutColor.Count == 1)
{
// If this is the first old line, wrap it in gray:
accumulatedText = grayOpenTag + previousLinesWithoutColor[0] + grayCloseTag;
}
else if (2 <= previousLinesWithoutColor.Count && previousLinesWithoutColor.Count < maxLines)
{
// If we're not at the max allowed lines yet, move the gray close tag to the end:
accumulatedText = accumulatedText.Replace(grayCloseTag, string.Empty) + grayCloseTag;
}
else if (previousLinesWithoutColor.Count >= maxLines)
{
// If we're at the max allowed lines, remove the topmost line from accumulatedText:
accumulatedText = grayOpenTag + accumulatedText.Substring(grayOpenTag.Length + previousLinesWithoutColor[0].Length);
accumulatedText = accumulatedText.Replace(grayCloseTag, string.Empty) + grayCloseTag;
previousLinesWithoutColor.RemoveAt(0);
}
base.SetContent(subtitle);
// Remove the possibly color-tagged current line from accumulated text, and add the non-color version:
accumulatedText = accumulatedText.Substring(0, accumulatedText.Length - (subtitle.formattedText.text + "\n").Length);
var currentLineWithoutColor = Regex.Replace(subtitle.formattedText.text, pattern, string.Empty) + "\n";
accumulatedText += currentLineWithoutColor;
previousLinesWithoutColor.Add(currentLineWithoutColor);
}
}
If you can identify any cases that break it, please let me know so I can update my post. This is the logic it uses:
Before displaying a new subtitle (called a "line" in the script):
If we've already displayed exactly one line, wrap that old line in rich text that colors it gray.
Otherwise if we're not at the max buffer size yet, accumulatedText will contain what's currently displayed, prior to showing the new line. Re-wrap all of this text in gray rich text.
Otherwise, if we're at the max, remove the topmost line from accumulatedText. (Maybe there's a logic issue here, and it needs to re-wrap it all in gray?)
Finally, add the new line to the accumulatedText in its original form, not gray.
After looking up all the weird string manipulation code I've never seen before and defining every little bit, I started getting a hang of what was going on.
You were correct about where the look for the problem!
else if (previousLinesWithoutColor.Count >= maxLines)
{
// If we're at the max allowed lines, remove the topmost line from accumulatedText:
accumulatedText = grayOpenTag + accumulatedText.Substring(grayOpenTag.Length + previousLinesWithoutColor[0].Length);
//move the gray close tag to the end:
accumulatedText = accumulatedText.Replace(grayCloseTag, string.Empty) + grayCloseTag;
previousLinesWithoutColor.RemoveAt(0);
}
It made it easier to test when I moved maxLines down to like 10. I didn't realize the reason I wasn't seeing the issue consistently was because I was rarely hitting 100 lines when testing.
------------
My next challenge is to just try to replace the common text with the grey text and leave the other color tags. This is a good exercise to learn all of this stuff.
Thanks! I'll update my code above with your fixes in case someone in the future (myself, most likely) stops reading there and forgets to check further down.