Max Dialogue Buffer
Max Dialogue Buffer
Howdy,
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?
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?
Re: Max Dialogue Buffer
Hi,
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:
TrimSubtitleText.cs
[EDIT: Fixed silly logic error.]
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:
TrimSubtitleText.cs
Code: Select all
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);
}
}
}
Re: Max Dialogue Buffer
Thanks for the reply - so I just got a chance to test this.
I adapted the code a little to get it to work:
Without the added bits, it seemed to just swap out the bottom line and leave the remaining first 1000 characters.
However, it seems to sometimes catch the middle of a color tag and warp the rest of the dialogue.
My next task was to address this issue:
https://www.pixelcrushers.com/phpbb/vie ... 771#p20771
Will solving that likely give me the tools to solve this issue as well?
Thanks
I adapted the code a little to get it to work:
Code: Select all
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)
{
string firstFiveHundredChars = accumulatedText.Substring(0, 500);
accumulatedText = DeleteStrTwoFromStrOne(accumulatedText, firstFiveHundredChars);
subtitlePanel.accumulatedText = accumulatedText;
}
}
public string DeleteStrTwoFromStrOne(string strOne, string strTwo)
{
return strOne.Replace(strTwo, "");
}
}
However, it seems to sometimes catch the middle of a color tag and warp the rest of the dialogue.
My next task was to address this issue:
https://www.pixelcrushers.com/phpbb/vie ... 771#p20771
Will solving that likely give me the tools to solve this issue as well?
Thanks
Re: Max Dialogue Buffer
Sorry about that logic error. I just fixed it in my post above by changing the "Substring" line to:
However, you're correct; in its current form it doesn't accommodate color codes. To handle color codes, you can make the script a little fancier:
TrimAndGrayPreviousTextSubtitlePanel.cs
(Edit: Fixed with @boz's addition below.)
Code: Select all
accumulatedText = accumulatedText.Substring(accumulatedText.Length - maxAccumulatedCharacters);
TrimAndGrayPreviousTextSubtitlePanel.cs
Code: Select all
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);
}
}
Re: Max Dialogue Buffer
Thanks!
That definitely did the trick, but I have no idea how it works.
I still managed to break it, but not consistently.
I'll have to do some studies on the techniques used here so I can fix it up to my liking.
That definitely did the trick, but I have no idea how it works.
I still managed to break it, but not consistently.
I'll have to do some studies on the techniques used here so I can fix it up to my liking.
Re: Max Dialogue Buffer
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):
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.
Re: Max Dialogue Buffer
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!
I copied this down to the 3rd if:
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 for your help as always
You were correct about where the look for the problem!
I copied this down to the 3rd if:
Code: Select all
accumulatedText = accumulatedText.Replace(grayCloseTag, string.Empty) + grayCloseTag;
Code: Select all
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);
}
------------
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 for your help as always
Re: Max Dialogue Buffer
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.