Feature suggestion: Make Chars Per Second take punctuation into account.

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
jjpixelc
Posts: 44
Joined: Sun Mar 01, 2020 1:04 pm

Feature suggestion: Make Chars Per Second take punctuation into account.

Post by jjpixelc »

Hi

Just an idea - wouldn't it be cool if the lifetime of a speechbubble (not typewriter) could take punctuation into account too?
Every full stop, comma, exclamation mark and so on would add a small amount of extra lifetime.
And the user should be ble to set the value for each separate punctuation mark type.

I'm making a bunch of cutscenes right now and it hit me that a feature such as this would make it much easier to automatically get the right flow in the conversations. Right now I set almost every node manually with its own specific length as the automated length based purely on number of characters in the node is rarely exaaactly as I want...

Anyway, what would I have to tinker with if I wanted to try and build this feature myself?
User avatar
Tony Li
Posts: 22134
Joined: Thu Jul 18, 2013 1:27 pm

Re: Feature suggestion: Make Chars Per Second take punctuation into account.

Post by Tony Li »

Hi,

Are you using the typewriter effect? If so, you can make the subtitle take as long as the typewriter plus some constant amount. For example, to make the subtitle stay for 1 second longer than the typewriter, use this sequence:

Code: Select all

Delay(1)@Message(Typed)
jjpixelc
Posts: 44
Joined: Sun Mar 01, 2020 1:04 pm

Re: Feature suggestion: Make Chars Per Second take punctuation into account.

Post by jjpixelc »

I'm not using typewriter.

But can I guess I can do the same like this:
Delay(X)@{{end}}
to make the bubble last for some extra time after the amount allotted by Chars Per Second?

I know I can get the subtitle text with: subtitle.formattedtext.
But the question is if I can get the text, analyse it for punctuation and then insert an extra delay into the node before the subtitle fires?
I could use a dialogue system variable for this (as the 'X' in Delay(X))- but I still need to change it before each node starts.
User avatar
Tony Li
Posts: 22134
Joined: Thu Jul 18, 2013 1:27 pm

Re: Feature suggestion: Make Chars Per Second take punctuation into account.

Post by Tony Li »

Hi,

You could use an OnConversationLine method. Example:

Code: Select all

using System.Linq;

public float fullPunctuationExtraDelay = 0.2f;
public float shortPunctuationExtraDelay = 0.1f;

void OnConversationLine(Subtitle subtitle)
{
    string text = subtitle.formattedText.text;
    float duration = ConversationView.GetDefaultSubtitleDurationInSeconds(text);
    int numFullPunctuation = text.Count(c => c == '.' || c == '!' || c == '?');
    int numShortPunctuation = text.Count(c => c == ',');
    duration += (numFullPunctuation * fullPunctuationExtraDelay) + (numShortPunctuation * shortPunctuationExtraDelay);
    subtitle.sequence = $"Delay({duration})";
}
jjpixelc
Posts: 44
Joined: Sun Mar 01, 2020 1:04 pm

Re: Feature suggestion: Make Chars Per Second take punctuation into account.

Post by jjpixelc »

I finished it and it's working great.

I'm very satisfied with the extra control and the more dynamic flow it gives conversations with practically no extra workload for me. It's especially great for longer cutscenes with no user input.
In my sequence-hectic, 3 minute, 36 node long testing cutscene, I only had to manually adjust subtitle lifetime in 2 places, and only because I'm pretty hysteric about subtitle timing :-)

Here's my finished code for anyone that might be interested.
I added a few things:
- Making sure the punctuation delay was added only to the end of the existing sequence, so the existing sequence is also played.
- A check to see if the punctuation delay is even relevant for this node before running any code.
- A small clean-up procedure at the end to get rid of excess semi colons.

(Sorry for all the Debug logs, just didn't bother removing them as I'm still testing the overall system)

Code: Select all

using System.Linq;

public float fullPunctuationExtraDelay;
public float shortPunctuationExtraDelay;
private int numberOfCharacters;

private void OnConversationLine(Subtitle subtitle)
    {
        numberOfCharacters = subtitle.formattedText.text.Length;
        string originalSequence = subtitle.sequence;
        Debug.Log($"(ID = {subtitle.dialogueEntry.id}): \"{subtitle.formattedText.text}\"");
        Debug.Log($"Original sequence: " + originalSequence);

        // ***Punctuation delay code***
        // Check if the sequence contains code that should cancel the punctuation delay:
        if (!originalSequence.Contains("None()") && !originalSequence.Contains("Delay")
            && !originalSequence.Contains("Continue()"))
        {
            // If sequnce does not contain forbidden code, add punctuation delay:
            string text = subtitle.formattedText.text;
            float duration = ConversationView.GetDefaultSubtitleDurationInSeconds(text);
            Debug.Log($"Characters = {numberOfCharacters}, Default duration = {duration}");
            int numFullPunctuation = text.Count(c => c == '.' || c == '!' || c == '?');
            int numShortPunctuation = text.Count(c => c == ',');
            duration += (numFullPunctuation * fullPunctuationExtraDelay) + (numShortPunctuation * shortPunctuationExtraDelay);
            Debug.Log($"FullP = {numFullPunctuation}, ShortP = {numShortPunctuation}, New duration = {duration}");

            // Build new sequence by adding punctuation delay to end of original sequence:
            var newSequence = subtitle.sequence + $";Delay({duration})";

            // Clean new sequence string:
            if (newSequence.Substring(0,1) == ";")
            {
                newSequence = newSequence.TrimStart(';');
            }
            if (newSequence.Contains(";;"))
            {
                newSequence = newSequence.Replace(";;", ";");
            }
            // Set subtitle sequence to the sequence we built:
            subtitle.sequence = newSequence;
            Debug.Log("New sequence: " + subtitle.sequence);
        }
        else
        {
            Debug.Log($"Canceling P-Delay, using original sequence: " + subtitle.sequence);
        }
    }
User avatar
Tony Li
Posts: 22134
Joined: Thu Jul 18, 2013 1:27 pm

Re: Feature suggestion: Make Chars Per Second take punctuation into account.

Post by Tony Li »

Thanks for sharing!
Post Reply