How to pause a game during a dialogue?

Announcements, support questions, and discussion for the Dialogue System.
Ondatr
Posts: 10
Joined: Wed Dec 07, 2016 7:54 am

How to pause a game during a dialogue?

Post by Ondatr »

In sequence field I wrote: SendMessage(togglePause,,GameManager)
which calls my function:

Code: Select all

private bool onPause = false;
    public void togglePause()
    {
        onPause = !onPause;
        if(onPause)
        {
            Time.timeScale = 0;
        }
        else { Time.timeScale = currentTimeScale; }
    }
However, it stops the game time only for a moment. Why? My function works fine when called by key input.
What is the best way to pause a game from a dialogue/during a dialogue?
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause a game during a dialogue?

Post by Tony Li »

Hi,

By default, the Dialogue System runs in realtime. This allows you to pause regular gameplay when running a conversation so the regular gameplay doesn't keep running while the player is in a conversation.

The DialogueTime class controls the Dialogue System's time mode. You may want to change the mode to gameplay mode instead to tell it to observe Time.timeScale:

Code: Select all

using PixelCrushers.DialogueSystem;
...
DialogueTime.Mode = DialogueTime.TimeMode.Gameplay; 
Alternatively, if you want the Dialogue System to keep using realtime mode, you can set DialogueTime.IsPaused:

Code: Select all

if(onPause)
{
    Time.timeScale = 0;
}
else { Time.timeScale = currentTimeScale; }
DialogueTime.IsPaused = onPause; 
Ondatr
Posts: 10
Joined: Wed Dec 07, 2016 7:54 am

Re: How to pause a game during a dialogue?

Post by Ondatr »

Tony Li wrote:Hi,

By default, the Dialogue System runs in realtime. This allows you to pause regular gameplay when running a conversation so the regular gameplay doesn't keep running while the player is in a conversation.
That is exactly what I'm trying to do. I have a counter Time.timeSinceLevelLoad, which stops if I'm calling my function by key input.
The same counter just freezes for a second if I'm calling the same function via the sequence. Why it behaves that way?
Alternatively, if you want the Dialogue System to keep using realtime mode, you can set DialogueTime.IsPaused:

Code: Select all

if(onPause)
{
    Time.timeScale = 0;
}
else { Time.timeScale = currentTimeScale; }
DialogueTime.IsPaused = onPause; 
On the first selection of the node which calls the function, Time.timeSinceLevelLoad counter stops but the dialogue nodes stop to show until I press continue; on the second selection the dialogue totally freeze.
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause a game during a dialogue?

Post by Tony Li »

Hi,

Thanks for the details. It sounds like perhaps SendMessage(togglePause,,GameManager) is being called twice. This would result in a pause followed by an unpause.

If you temporarily set the Dialogue Manager's Debug Level to Info, it will log a lot of information to the Console window. If you reproduce the problem, you should see a line like this:

Code: Select all

Dialogue System: Sequencer.Play( SendMessage(togglePause, , GameManager)@0 )
followed by a line like this:

Code: Select all

Dialogue System: Sequencer: SendMessage(togglePause, , GameManager (UnityEngine.Transform), )
The first line shows the plain text arguments to the SendMessage() sequencer command as well as the time that it will execute (the 0-second mark). The second line shows the actual values that the command will use (i.e., the GameManager GameObject that was found in the scene).

You may see two occurrences of these lines when your conversation is running. If so, it may indicate that two nodes have this sequencer command.

However, I suspect that you've hit a specific edge case. Is this sequencer command on the START node of the first conversation in the dropdown list? And is the Dialogue Manager's Preload Resources checkbox ticked? And does the conversation start as soon as the scene starts?

When Preload Resources is ticked, the Dialogue System does two things as soon as the scene starts:

1. If the Dialogue Manager's Dialogue UI field points to a prefab, it instantiates a copy of the prefab. (This typically isn't an issue if you're using Unity UI; just with others like legacy Unity GUI and NGUI.)

2. It executes the START node (but only the START node) of the first conversation. Some projects wait until the first conversation starts to initialize data (e.g., in an OnConversationStart method). This allows those projects to get that initialization out of the way, but it can also cause this edge case.

If this is the culprit, a quick solution is to untick Preload Resources.

If none of that helps, please feel free to send an example project to tony (at) pixelcrushers.com. I'll be happy to take a look.
Ondatr
Posts: 10
Joined: Wed Dec 07, 2016 7:54 am

Re: How to pause a game during a dialogue?

Post by Ondatr »

Ok, I have two cases where I call my function. First one I've created in the starting dialogue for testing/debug purpose yesterday, and it miraculously works today. All I did is remove

Code: Select all

DialogueTime.IsPaused = onPause; 
line as it was before my initial post.

The second, original, case was in the Start node of last conversation in the dropdown list. I moved the sequence to the second node and it works! So my problem is solved, thank you!

Additional info:

Code: Select all

Dialogue System: Sequencer.Play( SendMessage(togglePause, , GameManager)@0 )
followed by a line like this:

Code: Select all

Dialogue System: Sequencer: SendMessage(togglePause, , GameManager (UnityEngine.Transform), )
One occurrence of each line for every sequence execution;

Preload Resources checkbox is ticked;

Unity UI;

I will gladly send you my project if you think it's worth it.
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause a game during a dialogue?

Post by Tony Li »

Hi,

No need to send your project if it's all working now. It sounds like both cases are working. Is that correct?
Ondatr
Posts: 10
Joined: Wed Dec 07, 2016 7:54 am

Re: How to pause a game during a dialogue?

Post by Ondatr »

Correct. It's just I don't know why the sequence doesn't work as intended in the Start node of any dialogue (I've double checked).
Anyway, it doesn't matter for my gameplay for now.
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause a game during a dialogue?

Post by Tony Li »

Okay, thanks. I'll look into this just to close the loop, but I'm glad your project's working now.
Ondatr
Posts: 10
Joined: Wed Dec 07, 2016 7:54 am

Re: How to pause a game during a dialogue?

Post by Ondatr »

Okay, I'm still struggling and not sure if I'm doing something wrong. Let's try it one more time.

What is the correct way to pause regular gameplay during dialogues excluding given list of dialogues?

I will implement your solution. If it works - great. If not - I'll send you my project.
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to pause a game during a dialogue?

Post by Tony Li »

Ondatr wrote:What is the correct way to pause regular gameplay during dialogues excluding given list of dialogues?
If I understand you correctly, here's a way that uses a small script:

1. Add a custom Boolean field to your conversations named something like "PauseGameplay". In conversations that should pause gameplay, set the field to True.

(Side note: If you add this to your Conversation template on the Templates tab, tick the Main checkbox to auto-add it to each conversation and make it appear in the main editor part so you don't have to expand the All Fields foldout.)

2. Add to the Dialogue Manager a small script that checks this field and pauses/unpauses the game if appropriate:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class PauseGameplayDuringConversations : MonoBehaviour
{

    bool ShouldCurrentConversationPause()
    {
        var id = DialogueManager.CurrentConversationState.subtitle.dialogueEntry.conversationID;
        return Lua.IsTrue("Conversation[" + id + "].PauseGameplay");
    }

    void OnConversationStart(Transform actor)
    {
        if (ShouldCurrentConversationPause()) { /* pause */ }
    }

    void OnConversationEnd(Transform actor)
    {
        if (ShouldCurrentConversationPause()) { /* unpause */ }
    }
}
Post Reply