How to pause the game when the dialogue is shown

Announcements, support questions, and discussion for the Dialogue System.
NotoMuteki
Posts: 17
Joined: Mon Oct 11, 2021 9:48 pm

How to pause the game when the dialogue is shown

Post by NotoMuteki »

I'm creating the dialogue which is controlled by Timeline(with Conversation Track, Continue Conversation Track).
I want players to read the dialogue well, and hit "Continue" button to proceed.
But in order to do so, I have to pause the timeline when the dialogue is shown.

Pausing timeline is not ideal(because when the timeline is paused, all characters acting desired animations go back to idle animation on its Animator),
so setting time scale into 0, and after the player pushed "Continue", it goes back to 1 and proceed. This is my goal.

I set "Dialogue Time Mode" to "Gameplay" and put the Sequence "Pause()" in the entry,
expecting to be like when the dialogue is shown the time scale becomes 0 and pause.
But it didn't stop at all.
Is there anything I'm misunderstanding?
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause the game when the dialogue is shown

Post by Tony Li »

Hi,

The best way to pause a timeline is to set its speed to zero. For example, if you're using the Timeline() sequencer command:

Timeline(speed, Your Timeline, 0)

and then to resume the timeline:

Timeline(speed, Your Timeline, 1)

Don't use use Timeline(pause,...) or PlayableDirector.Pause() in C# because these will do what you described: they'll reset your animators, restart conversation dialogue entries, etc.
NotoMuteki
Posts: 17
Joined: Mon Oct 11, 2021 9:48 pm

Re: How to pause the game when the dialogue is shown

Post by NotoMuteki »

Awesome. Changing the speed of the timeline looks better.
Now problem is where and how to put those codes.

1. In my project all of dialogues are executed in the timeline,
so it would be better to write in Default Sequence.
Timelines differ in each dialogues, so how can I abstract it like:
Timeline(speed, currentTimeline, 0)?

2. Current Dialogue UI is "Basic Standard Usable UI" template, which typewrites the message text 1 by1 .
How can I stop the timeline when all the characters have been typed?
Writing sequence below didn't go well, stopped the timeline immediately.

Code: Select all

Timeline(speed, TestTimeline, 1);
Delay({{end}});
Timeline(speed, TestTimeline, 0)
3. I want to set the timeline speed back to 1 when "Continue" is pressed or when the player selected a response.
How can I achieve this?
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause the game when the dialogue is shown

Post by Tony Li »

Hi,
NotoMuteki wrote: Tue Oct 12, 2021 10:37 pm1. In my project all of dialogues are executed in the timeline, so it would be better to write in Default Sequence. Timelines differ in each dialogues, so how can I abstract it like:
Timeline(speed, currentTimeline, 0)?
If your timeline (Playable Director) is on the GameObject associated with the dialogue entry node's speaker, then you can omit the second parameter or set it to 'speaker':

Code: Select all

Timeline(speed, speaker, 0)
or:

Code: Select all

Timeline(speed, , 0)
(If the second parameter is blank, it is the same as using the special keyword 'speaker'.)
NotoMuteki wrote: Tue Oct 12, 2021 10:37 pm2. Current Dialogue UI is "Basic Standard Usable UI" template, which typewrites the message text 1 by1 . How can I stop the timeline when all the characters have been typed?
Like this:

Code: Select all

Timeline(speed, TestTimeline, 1);
Timeline(speed, TestTimeline, 0)@Message(Typed)
The typewriter effect sends the message 'Typed' when all characters have been typed. The second line of the sequence above waits to receive this message.
NotoMuteki wrote: Tue Oct 12, 2021 10:37 pm3. I want to set the timeline speed back to 1 when "Continue" is pressed or when the player selected a response. How can I achieve this?

Code: Select all

Timeline(speed, TestTimeline, 1);
Timeline(speed, TestTimeline, 0)@Message(Typed);
required Timeline(speed, TestTimeline, 1)@Message(Continued)
Nothing in the Dialogue System actually sends the message 'Continued'. This means the third line will wait forever. However, when you click the continue button, it will advance the conversation anyway. The 'required' keyword guarantees that the third line will run when you click the continue button, even if it hasn't received the 'Continued' message.

It may not be practical in your scenario to assume the timeline is on the speaker. Here are two solutions:

1. Set a variable to the name of the timeline. For example, say your timeline is on a GameObject named "Hart Timeline". You can set the variable named "Timeline" and start a conversation like this:

setTimelineVar.png
setTimelineVar.png (24.43 KiB) Viewed 688 times

(You can name the variable whatever you want.)

Then use a sequence like this:

Code: Select all

Timeline(speed, [var=Timeline], 1);
Timeline(speed, [var=Timeline], 0)@Message(Typed);
required Timeline(speed, [var=Timeline], 1)@Message(Continued)
At runtime, [var=Timeline] will be replaced by the value of the variable ("Hart Timeline").


2. If you don't want to do that, you can control it through scripting. Attach script methods to the typewriter effect's OnBegin() and OnEnd() UnityEvents. It may also help to use an OnConversationLine() special method on the Dialogue Manager. If you want to do this instead of suggestion #1 above, let me know and I'll sketch out some example code.
NotoMuteki
Posts: 17
Joined: Mon Oct 11, 2021 9:48 pm

Re: How to pause the game when the dialogue is shown

Post by NotoMuteki »

I put Playable Director component on the speaker object.
スクリーンショット 2021-10-14 231833.png
スクリーンショット 2021-10-14 231833.png (399.21 KiB) Viewed 672 times
Also wrote codes below in Default Sequence.

Code: Select all

Timeline(speed, speaker, 1);
Timeline(speed, speaker, 0)@Message(Typed);
required Timeline(speed, speaker, 1)@Message(Continued)
But the result is here:

It doesn't pause the timeline at all.

I'm not sure this is related, but this error comes up on start.

Code: Select all

Dialogue System: No Dialogue UI component found on Basic Standard Usable UI (UnityEngine.GameObject).
UnityEngine.Debug:LogError (object)
PixelCrushers.DialogueSystem.DialogueSystemController:LoadDialogueUIPrefab (UnityEngine.GameObject) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:1861)
PixelCrushers.DialogueSystem.DialogueSystemController:GetDialogueUIFromDisplaySettings () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:1824)
PixelCrushers.DialogueSystem.DialogueSystemController:ValidateCurrentDialogueUI () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:1809)
PixelCrushers.DialogueSystem.DialogueSystemController:GetDialogueUI () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:1766)
PixelCrushers.DialogueSystem.DialogueSystemController:get_dialogueUI () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:199)
PixelCrushers.DialogueSystem.DialogueSystemController:PreloadDialogueUI () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:659)
PixelCrushers.DialogueSystem.DialogueSystemController:PreloadResources () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:731)
PixelCrushers.DialogueSystem.DialogueSystemController:Start () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Manager/DialogueSystemController.cs:492)
Where am I actually misunderstanding?
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause the game when the dialogue is shown

Post by Tony Li »

Hi,

For the error: The Dialogue System has several types of UIs. Make sure you've assigned a dialogue UI such as 'Basic Standard Dialogue UI' to the Dialogue Manager's Dialogue UI field.

For the timeline issue, temporarily set the Dialogue Manager's Other Settings > Debug Level to Info. When the conversation gets to that sequence, check the Console log. Make sure the correct GameObject is being used for the speaker.
NotoMuteki
Posts: 17
Joined: Mon Oct 11, 2021 9:48 pm

Re: How to pause the game when the dialogue is shown

Post by NotoMuteki »

Thank you!
I set Dialogue UI back to ""Basic Standard Dialogue UI" from "Basic Standard Usable UI".
Now the error is gone and the timeline pause/resume is working as I expected!

This will get a little bit off the topic but,
I'm getting confused by "Conversation Track" and ""Continue Conversation Track".
イラスト.png
イラスト.png (135.21 KiB) Viewed 669 times
My expectation was like:
StartConversationClip; Start Dialogue(meaning move on to the first dialogue entry)
ContinueConversationClip: Move on to the next entry(the conversation won't progress until pass this clip)

But the current result is here:

After StartConversationClip was passed, the conversation proceeds regardless of ContinueConversationClip.
I want the dialogue to synchronize the character's animation and the camerawork.
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause the game when the dialogue is shown

Post by Tony Li »

Hi,

Add an instance of the Basic Standard Dialogue UI (or whatever dialogue UI prefab you're using) to the Dialogue Manager's Canvas, and assign it to the Dialogue Manager's Dialogue UI field.

Then edit this instance, and remove the subtitle panel's Continue Button. The timeline will advance the conversation by simulating a continue button click, so you don't need an actual continue button.

The problem with this sequence:

Code: Select all

Timeline(speed, speaker, 1);
Timeline(speed, speaker, 0)@Message(Typed);
required Timeline(speed, speaker, 1)@Message(Continued)
is that it pauses the timeline after the text has been typed. This means the timeline can't advance to get to the Continue Conversation clip.

This clip might be better:

Code: Select all

Delay(1)@Message(Typed)->Message(Delayed);
SendMessage(Close,,NPC Subtitle Panel)@Message(Delayed)
The first line will wait for the typewriter to finish, and then it will wait 1 second longer to give the player time to finish reading. Then it will send the message "Delayed".

The second line will wait for the "Delayed" message, and then it will hide the subtitle.

This sequence does not pause the timeline. This allows the timeline to continue playing so it can reach the Continue Conversation clip.
NotoMuteki
Posts: 17
Joined: Mon Oct 11, 2021 9:48 pm

Re: How to pause the game when the dialogue is shown

Post by NotoMuteki »

Of course by using the timeline, I want those dialogues are synchronized with character's animation, lipsync, and camerawork.
But as I mentioned in the first post, I want players to read the script well, and hit "Continue" button to resume(not just wait 1 second longer).
So that's why I need to pause the timeline.
Is there any way to achieve these 2 functions?

If my explanation wasn't enough, please take a look of this:

This is my old substitute system working with timeline.
Each dialogue is synchronized with animation and camerawork of timeline,
but in order to let the people read the dialogue it pauses the timeline.
I want to make something similar to this in Dialogue System for Unity.
User avatar
Tony Li
Posts: 21981
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause the game when the dialogue is shown

Post by Tony Li »

Hi,

I recommend connecting the "Continue" button to a different method that resumes the timeline and hides the subtitle panel but does not issue a "continue" message to the Dialogue System. Example method:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;
using UnityEngine.Playables;

public class ContinueButtonResumeSpeakerTimeline : MonoBehaviour
{
    public void ClickedContinueButton()
    {
        // Don't continue the conversation; the timeline will do that.
        // Instead, resume the timeline and hide the subtitle panel.
        DialogueActor dialogueActor;
        var subtitle = DialogueManager.currentConversationState.subtitle;
        var subtitlePanels = DialogueManager.standardDialogueUI.conversationUIElements.standardSubtitleControls;
        var panel = subtitlePanels.GetPanel(subtitle, out dialogueActor);
        panel.Close();
        subtitle.speakerInfo.transform.GetComponent<PlayableDirector>().playableGraph.GetRootPlayable(0).SetSpeed(1);
    }
}
Then configure the continue button's OnClick() event to call the ClickedContinueButton() method above.
Post Reply