Page 1 of 1

What's the way to know when a conversation line is fully displayed?

Posted: Mon Jan 17, 2022 10:11 am
by Jdedueass
Hi!
I'm trying to make the mouth of my NPC's move during conversations. Thing is, it works great! But I'd like to stop the mouth animation once a conversation line is fully displayed and the system is waiting for the player to press the continue button.

My first attempt was using OnConversationLineEnd, but this event is called once the player presses the continue button, so it does not work for my use case.

Is there another event or some built-in way in the plugin to know when a conversation line is fully displayed?

Re: What's the way to know when a conversation line is fully displayed?

Posted: Mon Jan 17, 2022 11:00 am
by Tony Li
Hi,

If you're talking about the end of the typewriter effect, it sends the sequencer message "Typed" to the sequencer when it's done. You can use a Sequence (or Dialogue Manager > Default Sequence) like this:

Code: Select all

AnimatorPlay(Talk);
required AnimatorPlay(Idle)@Message(Typed)
In the example above, the first line plays the "Talk" animation on the speaker. The second line plays the "Idle" animation when the typewriter is done, and 'required' guaranteees that the command runs even if the player skips ahead. (Technically the typewriter always sends Typed even if the player skips ahead, but it's good practice to use required for end-of-sequence commands like this that must run.)

Re: What's the way to know when a conversation line is fully displayed?

Posted: Tue Jan 18, 2022 3:57 am
by Jdedueass
Hi Tony and thank you!

Indeed, my aim is to stop the talk animation once the typewritter effect has stopped, and with the sequencer works awesome!

But I have a problem, and I can't find the way to replicate it in code, which is what I'd like to do. I'm not sure if I'll be clear enough but this is what I'm trying to achieve in pseudocode:

Code: Select all

class NPCStateMachine{
  	bool typewritterFinished = false;
  	
  	void OnTypeWritterEnd{
  		typewritterFinished = true;
  	}
  	
  	// Alternatively
  	//void SetupSequencer(){
        //   if(@Message(Typed))
        //        typeWritterFinished = true;
        //   else(@Message(TypedStarted)
        //        typeWritterFinished = false;
  	//}
  	
  	//void Awake(){ SetupSequencer(); }
  	
  	void Update(){
  	  if(typewritterFinished)
  	  	animation.StopTalking();
  	}
  	
}
I'm sorry if you already have answered this in the documentation, but I can't seem to find my way on it, I took a look to this page.https://www.pixelcrushers.com/dialogue_ ... ences.html

Re: What's the way to know when a conversation line is fully displayed?

Posted: Tue Jan 18, 2022 8:57 am
by Tony Li
You want your NPC state machine to react to the end-of-typing message instead of using sequencer commands, correct?

If so, here are two options:

1. Still use a sequencer command to listen for "Typed", but make it inform your state machine instead of directly controlling the animation. Example:
  • Sequence: SendMessage(FinishedTyping)@Message(Typed)

Code: Select all

// In your state machine on the speaker:
public void FinishedTyping()
{
    animation.StopTalking();
}
Alternatively, write a custom sequencer command. They're fairly simple to write, and it might make your sequence simpler to read, such as:
  • Sequence: StopTalking()@Message(Typed)

2. Or hook into the typewriter's OnEnd() UnityEvent. Add a script with an OnConversationLine method similar to this to the speaker:

Code: Select all

UnityUITypewriterEffect myTypewriterEffect; // Or TextMeshProTypewriterEffect if using TMPro

void OnConversationLine(Subtitle subtitle)
{
    if (subtitle.speakerInfo.transform == this.transform &&
        !string.IsNullOrEmpty(subtitle.formattedText.text))
    {
        // I'm speaking this line, hook into the typewriter effect:
        DialogueActor dialogueActor;
        var panel = DialogueManager.standardDialogueUI.conversationUIElements.standardSubtitleControls.GetPanel(subtitle, out dialogueActor);
        myTypewriterEffect = panel.subtitleText.GetComponent<UnityUITypewriterEffect>();
        
        if (myTypewriterEffect != null)
        {
            myTypewriterEffect.onEnd.AddListener(HandleTypingEnded);
        
            // Start talking:
            myStateMachine.StartTalking();
        }
    }
}

// This method is called by the typewriter's OnEnd() event since we hook it up to the event.
void HandleTypingEnded()
{
    // Unhook from the event:
    myTypewriterEffect.onEnd.RemoveListener(HandleTypingEnded);
    
    // Stop talking:
    myStateMachine.StopTalking();
}

Re: What's the way to know when a conversation line is fully displayed?

Posted: Fri Jan 21, 2022 3:43 am
by Jdedueass
Thanks Tony!!

The second option you mentioned is exactly what I'm looking for.

Thank you very much since I wasnt able to get it working by myself.

Re: What's the way to know when a conversation line is fully displayed?

Posted: Fri Jan 21, 2022 8:49 am
by Tony Li
Happy to help! :-)