Page 1 of 1

Talking animation pause during punctuation characters?

Posted: Sun Nov 01, 2020 2:23 pm
by AlvaroGode
Hello! Well, I've been searching about this topic and couldn't find anything, so apologies if it's already being asked. Pretty much the title says it all:
The project I'm building won't be using VA, so it will be more focused on text. There is a generic "talk" animation set in the actor's animator, and the dialogue system's default sequence is as follows:

Code: Select all

AnimatorBool(Talking,true,);
required AnimatorBool(Talking,false,)@Message(Typed)
Now, this works fine, but it also means that the actor would talk on punctuation characters. For example, when saying "..." the actor probably should open the mouth.
Also, this means that the typewriter effect's pause characters won't affect the talking animation in any way, meaning that the text would pause but the actor still moves the mouth. I'd like to find a way to syncronize this, or if there is a way to evaluate which characters are being written by the typewriter effect, so any help is much appreciated!

Thanks a ton!

Re: Talking animation pause during punctuation characters?

Posted: Sun Nov 01, 2020 4:16 pm
by Tony Li
Hi,

First, set the typewriter effect's Silent Characters field. Include all characters that the actor shouldn't talk on, such as ".,!?".

Then make a subclass of UnityUITypewriterEffect or TextMeshProTypewriterEffect (whichever one you're using) and override the PlayCharacterAudio() method. PlayCharacterAudio will only be called on characters that are not in the Silent Characters list. Example:

Code: Select all

Animator speakerAnimator;
public override void StartTyping(string text, int fromIndex = 0) // Cache speaker's Animator.
{
    base.StartTyping(text, fromIndex);
    speakerAnimator = DialogueManager.currentConversationState.subtitle.speakerInfo.transform.GetComponent<Animator>();
}

protected override void PlayCharacterAudio(char c) // Also control speaker's Animator.
{
    base.PlayCharacterAudio(c);
    speakerAnimator.SetTrigger("Talking");
}
Finally, replace the typewriter effect with your own version. If you change the Inspector to Debug mode, you can replace it in-place by dragging your script into the typewriter effect's Script field.


Alternatively, look into SALSA TextSync. It's a free addon for SALSA (which is a paid product) that syncs mouth movement to text. The Dialogue System has SALSA Support.

Re: Talking animation pause during punctuation characters?

Posted: Sun Nov 01, 2020 7:35 pm
by AlvaroGode
Hi! Thanks a ton! This works very nicely, but if I'm using a bool to toggle between the talking and non-talking animations, where should I put the

Code: Select all

speakerAnimator.SetBool("Talking", false);
I'm having some trouble checking where to hook up this.

Re: Talking animation pause during punctuation characters?

Posted: Sun Nov 01, 2020 7:51 pm
by Tony Li
You could override the big Play() method, but that's more trouble than it's worth. Instead, I recommend hooking into the OnCharacter() UnityEvent, which is called right after PlayCharacterAudio(). In PlayCharacterAudio, record that the speaker is talking and set the bool true. In the OnCharacter handler, if you haven't recorded that the player is talking, set the bool false. Example:

Code: Select all

private Animator speakerAnimator;
private bool isTalking;

public override void Awake()
{
    onCharacter.AddListener(CheckTalking);
}

public override void StartTyping(string text, int fromIndex = 0) // Cache speaker's Animator.
{
    base.StartTyping(text, fromIndex);
    speakerAnimator = DialogueManager.currentConversationState.subtitle.speakerInfo.transform.GetComponent<Animator>();
}

protected override void PlayCharacterAudio(char c) // Also control speaker's Animator.
{
    base.PlayCharacterAudio(c);
    speakerAnimator.SetBool("Talking", true);
    isTalking = true;
}

protected void CheckTalking()
{
    if (!isTalking) speakerAnimator.SetBool("Talking", false);
    isTalking = false; // Reset for next character.
}

Re: Talking animation pause during punctuation characters?

Posted: Sun Nov 01, 2020 11:05 pm
by AlvaroGode
Thank you so much Tony! This approach works really good. The only thing is that sometimes the bool doesn't seem to be set as false when the dialogue text finishes, so I just left the default sequence as

Code: Select all

required AnimatorBool(Talking,false,)@Message(Typed)
so it could have a failsafe of some sort.
Thanks again!

Re: Talking animation pause during punctuation characters?

Posted: Mon Nov 02, 2020 7:34 am
by Tony Li
That'll work. Or, to keep everything consistently within your typewriter effect subclass, you could hook into the OnEnd() event in the same way that you hook into OnCharacter():

Code: Select all

public override void Awake()
{
    base.Awake();
    onCharacter.AddListener(CheckTalking);
    onEnd.AddListener(DoneTalking);
}
...
protected void DoneTalking()
{
    speakerAnimator.SetBool("Talking", false);
}

Re: Talking animation pause during punctuation characters?

Posted: Mon Nov 02, 2020 12:35 pm
by AlvaroGode
Yeah, you're right, that seems like a better approach. Thank you so much for your help! It's now working beautifully :D

Re: Talking animation pause during punctuation characters?

Posted: Mon Nov 02, 2020 12:42 pm
by Tony Li
Glad to help!