Page 1 of 1

Skip pause between dialogue nodes

Posted: Sun Jul 19, 2020 7:44 pm
by Murble
This is a two part question.

First off, I was wondering how to skip the wait between displaying the next part of the conversation. I'm making a text adventure game and I am using the WRPG template for my dialogue, which shows all previous dialogue.
I know I can just group all the dialogue into a single node to make them all appear at the same time, however I like to have it separated by who is talking.
I removed the typewriter effect to make it appear instantly and made the subtitleCharsPerSecond = infinity and minSubtitleSeconds = 0, so no matter how many characters it has it should display the next line instantly. However, it waits till the next frame to display the next line, meaning it appears quickly, but not instantly. How can I make it so it instantly shows all of the lines in a conversation without any pause?

Then the second question is, how do I make it so when the conversation is finished, it stays displayed on screen?

To further explain what I want, I want it to instantly show all of a conversation on the screen, only pausing when the PC has to enter a response. Then when the conversation is finished, it will stay on screen for the player to read through it. Then when a new conversation starts, it will clear the history of the previous one.

Don't know if I'm explaining this well, and I can't think of any other games as an example.

I guess an example would be:
Image
I want the first 5 nodes to all appear at once,
then the player will be able to enter their response,
then the final three will show.
The conversation won't close to give the player time to read the final 3 that just appeared.

Re: Skip pause between dialogue nodes

Posted: Sun Jul 19, 2020 8:50 pm
by Tony Li
Hi,

Dialogue entry nodes always take at least 1 frame, which allows the sequencer to run its commands. If you set the Dialogue Manager's Default Sequence to "None()" and leave the entries' Sequence fields blank, they will only take 1 frame.*

To leave the conversation text visible after the conversation ends, you can provide your own implementation of IDialogueUI or extend StandardDialogueUI to not close the UI when the conversation ends. Here's an example of the latter:

DS_Immediate_LeaveVisible_2020-07-19.unitypackage


---
* If you absolutely don't want to allow 1 frame per entry, you can run the conversation manually. Create a ConversationModel and advance it manually. If you need more information on this, just let me know.

Re: Skip pause between dialogue nodes

Posted: Wed Jul 22, 2020 8:46 am
by Murble
Found a problem with this, or at least with the WRPG UI.
It has nothing to really do with your Dialogue System, and is a limit with unity. It being the 65000 vertices limit on meshes.
Reason for this being that since the history of all the text piles up and each character has many vertices which makes it soon hit that limit.

I can fix this by splitting up the subtitle text into multiple text UI's for each dialogue entry, so then there will be multiple meshes instead of one giant mesh of text.

To do this I feel I would have to disable the Accumulate text option on the Subtitle Panel to make sure it doesn't make the giant mesh of all text anymore. And whenever it displays a new subtitle, it would instead have to instantiate that into the scroll content. Then I have to also make sure the subtitleText on the subtitle panel info is set to nothing, so it doesn't try and write two of these.

Which I think I can do with something that looks like:

Code: Select all

public List<Text> displayedText = new List<Text>(); // allows me to go back and edit text if wanted
public Text subtitleTextPrefab; // grabbing a prefab so I don't have to set all the font size settings or anything.
public Transform subtitleHolder; // where the subtitleText used to be. Now an empty gameObject with a vertical layout on it

void OnConversationLine(Subtitle subtitle)
{
        Text newText = Instantiate(subtitleTextPrefab, subtitleHolder) as Text;
        newText.text = subtitle.formattedText.text;
        displayedText.Add(newText);
}
Then when a new conversation starts, I would go through the displayedText list and delete all the subtitle gameObjects then clear the list to start from scratch.
Which, similar to what you wrote would look somewhat like (Haven't tested this part yet, so may be wrong):

Code: Select all

public virtual void OnConversationStart(Transform actor)
{
        ClearText(); //Which I won't really need anymore since I disabled accumulate text. But keeping it
        foreach(Text text in displayedText)
        {
        	Destroy(text.gameObject);
        	displayedText.Remove(text);
        }
}
I'm pretty crappy with coding, which is why I use node based editors to help visualize things. So, is this a decent idea? It works but, is it sloppy? Also, is there a native way of separating subtitleTexts with Dialogue System(which is what I should have asked at first)?

Re: Skip pause between dialogue nodes

Posted: Wed Jul 22, 2020 10:13 am
by Tony Li
There are a few ways to approach this.

You can use the TextlineDialogueUI script found in the Textline template on the Extras page. It does what you describe. There's also an extra version for Enhanced Scroller, which is another asset on the Asset Store.

Or you can simply trim the top part of the text as you accumulate. So as the conversation gets longer, you trim off the early part to stay under the 65K limit.

To do that, make a subclass of StandardUISubtitlePanel, such as:

MySubtitlePanel.cs

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;
public class MySubtitlePanel : StandardUISubtitlePanel
{
    // Trim the accumulated text if it gets longer than this:
    public int maxCharsToAccumulate = 10000; // (Set in Inspector)
    
    public override void SetContent(Subtitle subtitle)
    {
        // If the accumulated text would be too long, trim it first:
        var newContentLength = subtitle.formattedText.text.Length;
        if (accumulatedText.Length + newContentLength > maxCharsToAccumulate)
        {
            accumulatedText = accumulatedText.Substring(0, accumulatedText.Length - newContentLength);
        }
        
        // Then add the new content:
        base.SetContent(subtitle);
    }
}
Then replace your StandardUISubtitlePanel component with your custom class. An easy way to do this while retaining all the field assignments is:

1. Inspect the StandardUISubtitlePanel.
2. In the Inspector's menu in the upper right, change the view from Normal to Debug.
3. Drag your custom class's script into the StandardUISubtitlePanel component's Script field.