Wait for hide animation before showing line

Announcements, support questions, and discussion for the Dialogue System.
alfa995
Posts: 30
Joined: Mon Dec 03, 2018 11:31 pm

Wait for hide animation before showing line

Post by alfa995 »

Hi!

I'm trying to implement a system with two dialogue ui components (PC and NPC, same as basic standard) and the fast forward continue button. When one of them is speaking and then the other has a line, the first one fades out and the next one fades in, with Show and Hide animations, but these happen at the same time. I'd like to know if there's a way for the second ui to wait until the first ui's Hide animation finishes before appearing.

I tried using the manager's default sequence and adding a required Delay(_)@{{end}}, but it just holds the previous line, and they both play their animations at the same time anyway.

Basically I'd need a way to run lua code after 'hide' animations finish and for the system to wait until that code finishes before showing the next line. Similar to default sequences, it'd need to be able to run code by default, but allow it to be overriden (to add a longer wait or play animations after a particular line, for example). I'm fairly new to the system so I'm not even sure if it's possible, or how complicated it'd be.

Any guidance is appreciated, thanks!
User avatar
Tony Li
Posts: 20759
Joined: Thu Jul 18, 2013 1:27 pm

Re: Wait for hide animation before showing line

Post by Tony Li »

Hi,

The built-in dialogue UI scripts are designed to kick off the next line's show animation as soon as it kicks off the current line's hide animation.

If you're comfortable with scripting, you can override this behavior. If you want to do this, let me know; I'll describe how.

If you'd prefer to avoid scripting, you can add a delay to the beginning of the show animation that's equal to the length of the hide animation. For example, if the hide animation takes 0.5 seconds, then you can design the first 0.5 seconds of your show animation to do nothing; after 0.5 seconds, it can start showing the panel.

Another non-scripting alternative is to set the Default Sequence and Default Player Sequence to manually close the panel using a sequencer command similar to this:

Code: Select all

SendMessage(Close,,NPC Subtitle Panel)@{{end}}; Delay(0.5)@{{end}}
The only catch is that this won't work with the continue button, which forces the conversation to immediately continue to the next line.
alfa995
Posts: 30
Joined: Mon Dec 03, 2018 11:31 pm

Re: Wait for hide animation before showing line

Post by alfa995 »

Thank you for your suggestions! I'm ok with scripting, so if there's a way to override the continue button or create different behavior that allows lua to run before starting the next line please let me know!
User avatar
Tony Li
Posts: 20759
Joined: Thu Jul 18, 2013 1:27 pm

Re: Wait for hide animation before showing line

Post by Tony Li »

Here's an example scene:

AlfaExample_2019-05-23.unitypackage

And the script it uses:
QueueSubtitleDialogueUI .cs

Code: Select all

using UnityEngine;
using PixelCrushers;
using PixelCrushers.DialogueSystem;
using System.Collections;

public class QueueSubtitleDialogueUI : StandardDialogueUI
{
    [Tooltip("If subtitle isn't hidden after this duration, maybe it's hung up. Allow conversation to continue.")]
    public float maxSecondsToWaitForHideSubtitle = 5;

    private StandardUISubtitlePanel currentVisiblePanel = null;

    public override void ShowSubtitle(Subtitle subtitle)
    {
        var panel = subtitle.speakerInfo.isNPC ? conversationUIElements.defaultNPCSubtitlePanel : conversationUIElements.defaultPCSubtitlePanel;
        var isDifferentPanel = panel != currentVisiblePanel && currentVisiblePanel != null;
        if (isDifferentPanel)
        {
            StartCoroutine(ShowSubtitleWhenOtherPanelIsHidden(subtitle, panel));
        }
        else
        {
            base.ShowSubtitle(subtitle);
            currentVisiblePanel = panel;
        }
    }

    IEnumerator ShowSubtitleWhenOtherPanelIsHidden(Subtitle subtitle, StandardUISubtitlePanel newPanel)
    {
        currentVisiblePanel.Close();
        var timeout = Time.time + maxSecondsToWaitForHideSubtitle;
        while (currentVisiblePanel.panelState != UIPanel.PanelState.Closed && Time.time < timeout)
        {
            yield return null;
        }
        base.ShowSubtitle(subtitle);
        currentVisiblePanel = newPanel;
    }

    public override void Close()
    {
        currentVisiblePanel = null;
        base.Close();
    }

}
The script is included in the unitypackage. I also included the non-script version in case you want to check it out.

The script is pretty simple. It's a subclass of StandardDialogueUI that overrides ShowSubtitle. If another subtitle panel is visible, it hides it and waits until it's hidden before showing the new subtitle. For simplicity, it just uses the default NPC & PC subtitle panels. You could expand it to work more generally if needed.
alfa995
Posts: 30
Joined: Mon Dec 03, 2018 11:31 pm

Re: Wait for hide animation before showing line

Post by alfa995 »

Thank you for the package! I tried it in a fresh project but it seems to hide the continue button after the first line though.

Also I realize this is probably outside the scope of the original question but.. if there were something similar to sequences, but not during lines and instead after they're continued and before the next one appears, that'd probably solve this problem and many others. For example, a character says a line, the player continues, then the character walks away, turns around and says their next line, like short cutscenes inbetween the dialogue.

It's probably too complex and seems more like a system-wide feature rather than dealing with a small user-specific problem, but it'd allow a ton of flexibility. The hide animation problem could then be fixed with something like "Default Late Sequence: Delay([length of hide animation])" which would just wait a bit after the player continues, and then show the next line, and if a line needs to do more, a specific Late Sequence would be written for it in the database.

Again sorry for the complicated question, but maybe others could benefit from such a feature too so I thought I'd mention it.
User avatar
Tony Li
Posts: 20759
Joined: Thu Jul 18, 2013 1:27 pm

Re: Wait for hide animation before showing line

Post by Tony Li »

That just requires a line or two of extra code. I updated the unitypackage above. The updated script is:
QueueSubtitleDialogueUI.cs

Code: Select all

using UnityEngine;
using PixelCrushers;
using PixelCrushers.DialogueSystem;
using System.Collections;

public class QueueSubtitleDialogueUI : StandardDialogueUI
{
    [Tooltip("If subtitle isn't hidden after this duration, maybe it's hung up. Allow conversation to continue.")]
    public float maxSecondsToWaitForHideSubtitle = 5;

    private StandardUISubtitlePanel currentVisiblePanel = null;
    private bool showContinueButton = false;

    public override void ShowSubtitle(Subtitle subtitle)
    {
        var panel = subtitle.speakerInfo.isNPC ? conversationUIElements.defaultNPCSubtitlePanel : conversationUIElements.defaultPCSubtitlePanel;
        var isDifferentPanel = panel != currentVisiblePanel && currentVisiblePanel != null;
        if (isDifferentPanel)
        {
            StartCoroutine(ShowSubtitleWhenOtherPanelIsHidden(subtitle, panel));
        }
        else
        {
            base.ShowSubtitle(subtitle);
            currentVisiblePanel = panel;
        }
    }

    public override void ShowContinueButton(Subtitle subtitle)
    {
        showContinueButton = true;
        base.ShowContinueButton(subtitle);
    }

    IEnumerator ShowSubtitleWhenOtherPanelIsHidden(Subtitle subtitle, StandardUISubtitlePanel newPanel)
    {
        currentVisiblePanel.Close();
        var timeout = Time.time + maxSecondsToWaitForHideSubtitle;
        while (currentVisiblePanel.panelState != UIPanel.PanelState.Closed && Time.time < timeout)
        {
            yield return null;
        }
        base.ShowSubtitle(subtitle);
        currentVisiblePanel = newPanel;
        if (showContinueButton)
        {
            base.ShowContinueButton(subtitle);
            showContinueButton = false;
        }
    }

    public override void Close()
    {
        currentVisiblePanel = null;
        base.Close();
    }
}
alfa995 wrote: Thu May 23, 2019 4:00 pm...if there were something similar to sequences, but not during lines and instead after they're continued and before the next one appears, that'd probably solve this problem and many others.
Devs usually handle this by having a dialogue entry node (or even a series of nodes) that hides the dialogue UI.

That node's Sequence might look something like:

Code: Select all

SetDialoguePanel(false);
AnimatorPlayWait(WalkAway)->Message(Done);
required SetDialoguePanel(true)@Message(Done)
Another way to do it is to use Timeline. Personally, my workflow is faster if I sequence it all in the Dialogue Editor. But if you have very long, complicated sequences, you can set them up in Timeline and manually advance a conversation using the Dialogue System's Timeline actions.
alfa995
Posts: 30
Joined: Mon Dec 03, 2018 11:31 pm

Re: Wait for hide animation before showing line

Post by alfa995 »

A dialogue entry node would be a node with no text, just a sequence right? I guess that's a good way to do it, thanks!

The package still seems buggy though, the continue button fast forward doesn't hide on continue even when the option is toggled on, when "Not Before Response Menu" is selected sometimes it still shows up, or it continues automatically before choosing a response, etc.

I'm sorry I keep asking and complaining, I just feel so lost. The Dialogue System's code is so complex it's overwhelming and even after checking the manual and tutorials I can't figure out how to make even simple extensions to functionality.
User avatar
Tony Li
Posts: 20759
Joined: Thu Jul 18, 2013 1:27 pm

Re: Wait for hide animation before showing line

Post by Tony Li »

Yes, use a dialogue entry node with no text and only a sequence.

Sorry about the issues with the custom script. I've been trying to keep it as simple as possible, but this means I've omitted some checks for things like what you pointed out.

However, it may all be a moot point if you end up using a dialogue entry with node text and only a sequence instead of a custom subclass dialogue UI script.
alfa995
Posts: 30
Joined: Mon Dec 03, 2018 11:31 pm

Re: Wait for hide animation before showing line

Post by alfa995 »

Yeah I think the animation-based solution you suggested is probably best in this case, and entry nodes/timeline for more complicated stuff. Sorry for the trouble and thanks again for your help!
User avatar
Tony Li
Posts: 20759
Joined: Thu Jul 18, 2013 1:27 pm

Re: Wait for hide animation before showing line

Post by Tony Li »

Glad to help.
Post Reply