Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Announcements, support questions, and discussion for the Dialogue System.
FredericoUnO
Posts: 7
Joined: Tue Sep 21, 2021 4:04 pm

Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by FredericoUnO »

Hello,

I've been having some trouble getting scene transitions to work exactly how I want them to while using the dialogue system and I want to see if you have a suggestion for a better way to achieve my intended outcome. Forgive me for what's going to be a long post. I want to try to give sufficient details about the problems and what I've tried to fix them.

How I transition between scenes (in case it's relevant): I have a few different scene transition functions, each of which utilizes the SceneManager.LoadScene() function (using the default single mode, not additive). In each of my scenes, one of these functions gets called either in the final conversation node within the Dialogue window, in the "On Conversation End (Transform)" Conversation Event of the Dialogue System Events component attached to my dialogue manager object, or in the OnConversationEnd() function in a script attached to my dialogue manager object.

Initial Problem:

When loading a new scene, elements from the previous scene would remain visible and obstruct the view of the new scene. I made a couple quick mockup scenes using some built in pixel crushers assets to demonstrate what I'm describing:

Game View:
OverlapExample.PNG
OverlapExample.PNG (139.54 KiB) Viewed 2131 times
Zoomed Out Scene View:
SceneView1.PNG
SceneView1.PNG (116.5 KiB) Viewed 2131 times
Between the pictures, you can see that the bottom left corner of the previous scene is overlapping with the new scene. I realized that this was at least partially caused by the fact that the visual elements of the previous scene were children of the dialogue manager. Since the dialogue manager was set to "Don't Destroy On Load," these visual elements persisted between scenes. I don't know why the previous scene elements appear so much larger than those of the new scene, though. They are set to the same size within their own scenes.

Initial Solution:
My initial solution to this problem was to uncheck "Don't Destroy On Load" for my dialogue manager object so that the previous scene's elements would get destroyed and all that would be used in the new scene was the elements pertaining to that scene. Unfortunately, this required the (I think) computationally intensive acts of instantiating and destroying a dialogue manager object for each scene. Additionally, it meant my dialogue database variables would get reset between scenes, requiring me to save them at the end of each scene and load them almost immediately after, once the new scene had been loaded.

To try to remedy these unfortunate byproducts of my initial solution, I decided to recheck the "Don't Destroy On Load" option and move all of the objects that weren't part of the Dialogue UI out from under the dialogue manager in the hierarchy and onto a separate canvas under the Main Camera. This loads the new scene and destroys the objects from the previous scene that are not part of the dialogue UI, as intended.

New Problem:
Since I am no longer destroying the dialogue manager when changing scenes, the dialogue manager from the first scene with dialogue persists through the remainder of the scenes, meaning the dialogue UI associated with that dialogue manager is what's used in each of the subsequently loaded scenes. I have a default dialogue UI prefab that I use as the basis for most of my scenes, but most of the scenes have different variations of that UI, whether its different subtitle locations depending on the location of the corresponding actor's sprite or additional subtitle panels for when there are more than two actors involved in the conversation. Since the dialogue manager from the initial dialogue scene and, subsequently, its dialogue UI, are what are being used in each new scene that gets loaded, none of these custom dialogue UIs are used when they should be used.

Additionally, I have a variable that is set as a serialized field within a script attached to my dialogue managers. This object is manipulated based on conversation conditions. It is set as one of the objects in my hierarchy. If I leave that object under the dialogue manager in the hierarchy, the new scene uses the old instance of the variable from the previous scene when it should be using the object within the new scene. Conversely, if I move the object to the canvas that is not attached to the dialogue manager with the other visual elements, it causes an error in the script that tries to manipulate it since the instance that the script is trying to manipulate gets destroyed. A workaround for this is to check if the stored instance is null and, if so, use GameObject.Find() to get the object of the same name in the new scene hierarchy. While this works, I would prefer a solution that retrieves the actual object stored in the serialized field in the new scene's dialogue manager.

Secondary Problem:
I implemented a skip button in my dialogue using the example here and it worked perfectly when I was destroying/instantiating the dialogue manager with each scene change. Since changing to my second method where I don't destroy the dialogue manager, the skipping function does not stop at the end of a scene/conversation (I included the OnConversationEnd(){skip = false} method that was suggested after the initial post in that thread). I used a debug log message to check and confirm that the skip variable is getting set to false in the OnConversationEnd() function, but, for some reason, it continues to skip conversation lines when the new scene gets loaded. If the new scene has a conversation node split that requires a user response, the conversation stops as if the node before the split was the last node in the conversation. I did some additional testing by setting the subtitle panel of one of the actors in the new scene to a custom subtitle panel (the "correct" panel for that character under the dialogue UI object in that scene) and that caused the skipping to stop on that actor's first line of dialogue in the new scene. It seems that, for some reason, the skipping doesn't stop if the dialogue UI doesn't change.

Potential Solution:
The best solution I can come up with for my dialogue UI problem is to add all of my different possible subtitle panels to the list of subtitle panels in the Standard Dialogue UI component of the dialogue UI object in the first scene with dialogue. Since that dialogue UI is what's used in every subsequent scene, I can set each character's subtitle panel number to the appropriate index in that list. This seems very tedious and bothersome to have so many different subtitle panels in that UI, but it's at least doable, assuming I don't exceed an upper limit on the number of subtitle panels that can be added to the list.
An alternative solution I thought of was to set the subtitle panel number to "Custom" for each actor in each scene and just drag in the corresponding subtitle panel for that particular actor to the custom subtitle panel field. Unfortunately, this did not work as intended. When the new scene gets loaded, a clone of the custom dialogue panel gets added as a child to the corresponding actor's sprite and appears much larger than it should be:

Zoomed Out Scene View:
SceneViewFullyZoomedOut_LI.jpg
SceneViewFullyZoomedOut_LI.jpg (878.67 KiB) Viewed 2131 times
The blue arrow points to the custom dialogue panel. The red arrow points to the dialogue UI that persisted from the previous scene. The yellow arrow points to the current scene, showing how small it is in comparison to the other two.

Partially Zoomed In Scene View:
SceneView2.PNG
SceneView2.PNG (34.33 KiB) Viewed 2131 times
This allows you to more clearly see the canvas containing the non-dialogue UI elements of the new scene


Game View:
GameView.PNG
GameView.PNG (388.85 KiB) Viewed 2131 times
The response menu from the dialogue UI attached to the dialogue manager is visible, but the custom dialogue panel is not.

I can technically work around this issue by applying very small scaling factors to the custom dialogue panels and potentially adjusting their positional offsets, but this seems like a much more tedious solution than the subtitle panel list solution I mentioned above.

Ultimately, I don't like either of my solutions to the problems I've had because they seem pretty dirty/hacky, which makes me think there has to be a better way to do this. I'm also not sure what to do about the skip button issue. Do you have any recommendations of a better way to do what I'm trying to do? I think, ideally, I would want to somehow be able to apply the properties of the new scene's dialogue manager to the already existing dialogue manager instance, but I don't know if that is possible.
User avatar
Tony Li
Posts: 21984
Joined: Thu Jul 18, 2013 1:27 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by Tony Li »

Hi,

Version 2.2.20+ has a Conversation Control component that you can add to a dialogue UI. It's similar to the example you linked. It has methods such as SkipAll() and ToggleAutoPlay() that you can hook up to UI buttons.

Generally speaking, Unity works at two different scales:
  • The world space scale is what the camera sees, such as your player and NPC GameObjects.
  • The screen space scale is much bigger. It's the coordinate system used by Unity UI Screen Space canvases.
In your "Zoomed Out Scene View" screenshot, the small area in the bottom left looks like it's the world space stuff, and the larger image is the screen space stuff.

I recommend something like this:
  • Keep the Dialogue Manager's Other Settings > Don't Destroy On Load checkbox ticked.
  • Assign your main dialogue UI (the one you use most of the time across most scenes) to the Dialogue Manager's Dialogue UI field.
  • If there are other subtitle panels or menu panels that you use more than one, add them to the main dialogue UI. To use one of these other panels, set the character's Dialogue Actor component > Dialogue UI Settings > Subtitle Panel Number, or use [panel=#] tags or SetPanel() sequencer commands.
  • For one-off dialogue UIs, add an Override Dialogue UI component to the character, and assign a dialogue UI.
Also, if you're thinking of using the Dialogue System's Save System, consider using PixelCrushers.SaveSystem.LoadScene() instead of SceneManager.LoadScene(). It does the same thing that SceneManager.LoadScene() does, but it also ties into the save system by recording scene data before leaving the old scene, and apply recorded scene data after entering the new scene. It will also work with a Scene Transition Manager component if you want scene transitions such as fading out & in or showing an intermediate loading screen.
FredericoUnO
Posts: 7
Joined: Tue Sep 21, 2021 4:04 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by FredericoUnO »

Thank you for the fast reply, Tony!

I guess I was on the right track with my subtitle panel list solution.

In regard to the save system, I was actually using
saveState = PersistentDataManager.GetSaveData()
and PersistentDataManager.ApplySaveData(saveState)
as all I cared about was saving the dialogue database information. Would PixelCrushers.SaveSystem.LoadScene() work better for that purpose as well?

For the skip button, we're using version 2.2.15, so I'll work on upgrading it to use your solution. Out of curiosity, do you know why the example I linked doesn't work in this case? I did some additional testing and realized my initial evaluation of where it is stopping was incorrect. It is not ending the conversation on the node just before a response is required. Instead, it seems to just quit processing the conversation after the first node with dialogue after the start node in the new conversation (the reason for my previous error was that I had a response right after this node). From my testing, it's showing a couple different behaviors:
1.) If I go directly from the Start node into a node with dialogue, the subtitle panel and continue button for this node flash on the screen, then quickly disappear. The Skip button is still visible, but clicking it does nothing.
2.) If I add an animation before the first node with dialogue in the new conversation (Either a "Fade(in, x)" sequence in the Start node or a sprite animation in a node without dialogue in between the Start node and the first node with dialogue), the skip button, dialogue panel, and continue button for the first node with dialogue all appear and remain visible as they should, but clicking the buttons has no effect.
User avatar
Tony Li
Posts: 21984
Joined: Thu Jul 18, 2013 1:27 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by Tony Li »

Hi,

Given how you're saving data, the only reason to use SaveSystem.LoadScene() would be if you wanted to use a StandardSceneTransitionManager component. But if you're managing scene changes and transitions on your own already, no need to worry about that.

For the skip button, please let me know if the ConversationControl component in 2.2.20 does the trick. It might have the same behavior. If so, please reply with reproduction steps from a blank scene or, even better, send a reproduction project to tony (at) pixelcrushers.com.
FredericoUnO
Posts: 7
Joined: Tue Sep 21, 2021 4:04 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by FredericoUnO »

Hey Tony,

I'm having a problem implementing the solution you suggested. When I change scenes, the first line of dialogue in the new scene flashes on screen briefly, then the dialogue panel is deactivated somehow, preventing me from progressing the conversation (it normally proceeds with continue buttons, but the currently active subtitle and continue button get deactivated with the dialogue panel). Do you have any idea what might be causing this to happen? From the brief flash of the initial subtitle panel, I can see that the custom subtitle panels are being set properly using the persisting dialogue manager. As far as I can tell, the only issue is that the dialogue panel that contains all of the subtitle and response menu panels is being deactivated. Perhaps I overlooked something that is causing this deactivation?

Here are the steps I took to change how my scene transitions work:
1. In my custom Dialogue UI prefab, I added subtitle panels for each of the different variations I have in my scenes as children of the Dialogue Panel element that is a child of the Dialogue UI. I then added each of those subtitle panels to the Subtitle Panels list in the Standard Dialogue UI component of the Dialogue UI element.
2. In each of my scenes, I moved the elements unrelated to dialogue out from under the Dialogue Manager and to a canvas that is a child of the main camera. For each of the dialogue actors, I changed their subtitle panel number to match the appropriate panel in the Dialogue UI subtitle panel list.
3. I created a custom Dialogue Manager prefab with the new custom Dialogue UI and checked the Do Not Destroy On Load checkbox. I then used that prefab to replace the dialogue managers in each "initial" scene where the persisting dialogue manger could first be used.
4. I removed the Dialogue Manager element from "non-initial" scenes as they would utilize the Dialogue Manager from an initial scene with the Do Not Destroy on Load box checked.
5. In any scene that relied on a "On Conversation End" event from a Dialogue System Events component to change scenes, I changed the cause of the scene change to a scene event function call on a new final node within the corresponding dialogue conversation.

Edit: Looking into the animator, I can see that the Hide animation is being activated before the dialogue panel gets deactivated. This seems to be the reason the dialogue panel is being deactivated as the "Deactivate On Hidden" checkbox in the dialogue panel's UI Panel component is checked. Running the scene transition without that box checked keeps the dialogue panel active, but still hidden and unusable.
Last edited by FredericoUnO on Wed Sep 29, 2021 12:59 pm, edited 1 time in total.
User avatar
Tony Li
Posts: 21984
Joined: Thu Jul 18, 2013 1:27 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by Tony Li »

Hi,

Please try this:

1. Back up your project.

2. Import this package:

DS_BubblePanelPatch_2021-09-23.unitypackage

It says "bubble subtitle patch" but it contains some updates for dialogue UIs in general that may simplify things.

3. Tick the "Wait for Close" checkbox on the Standard Dialogue UI component and the subtitle panels.
FredericoUnO
Posts: 7
Joined: Tue Sep 21, 2021 4:04 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by FredericoUnO »

Thanks, Tony! That seems to have fixed that problem!

Unfortunately, it's also revealed/led into another, less significant issue: Some of my scenes end with an NPC asking the player a question that prompts a response menu. The different responses dictate which scene gets loaded next. The scene loading is done via a scene event on the conversation nodes corresponding to each of the responses. The events each call different functions from a scene loading script. The script has different scene loading functions to fit different needs (each uses the SceneManager.LoadScene() method to load a scene, but different logic to determine what scene gets loaded, among other things). The new issue is that when I switch scenes this way, the dialogue from the NPC asking the question in the first scene remains on screen until dialogue in the new scene replaces it. This isn't a problem when dialogue starts right away in the new scene, but it is a problem if there is a delay in starting the new scene's conversation, such as first fading into the scene or playing some other animation.

I can "fix" the problem by changing the subtitle panel visibility from "Until Superceded" to "Only During Content", but this has the undesirable side effect of the speech bubbles for that subtitle panel continuously fading out and reappearing when consecutive conversation nodes are spoken by the same actor. This is a passable work around for now, but I wanted to check to see if you have a better solution for the issue. Thanks again for all your help.

Side note that seems like it could be related: Upgrading the dialogue system to a newer version and/or incorporating those dialogue UI updates from your previous post seem to have fixed my skip button function issues. The script I was using before is working as intended now. Interestingly, the Conversation Control component/script does not work as well for me. It works in most scenes, but in the scenes that transition based on player responses (the same ones described above), it causes an error. When I skip to the final response menu in those scenes and select a response that would otherwise cause a scene transition, I get a "Dialogue System: Another conversation is already active. Not starting {new scene name}" error. This error does not occur if I use the old skip button script I linked in my initial post, nor if I click through the conversation normally using continue buttons rather than the skip button.
User avatar
Tony Li
Posts: 21984
Joined: Thu Jul 18, 2013 1:27 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by Tony Li »

Hi,

When the final node ends, the dialogue UI should close. Is it possible that the final node isn't ending? Although it sounds more like the dialogue UI is somehow getting orphaned. I still don't have a perfectly clear idea of how it's set up, but you can try to use the SetDialoguePanel(false, immediate) sequencer command in the final node(s) to close the UI.
FredericoUnO
Posts: 7
Joined: Tue Sep 21, 2021 4:04 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by FredericoUnO »

Hey, Tony,

I don't think that option works. Using the SetDialoguePanel(false, immediate) sequencer command in the final nodes mostly hides the subtitle panel in the new scene, but a small fragment of the dialogue panel still briefly appears on the screen before the new dialogue starts. Additionally, this change creates a long delay in subtitle panel transitions in the new scene (for me, it took approximately 8 seconds after clicking the continue button for the new subtitle panel to appear).

Interestingly, reverting the subtitle panels to not having the Wait For Close box checked eliminates this delay and does not cause the issue I was previously having with dialogue in the new scenes not progressing. Perhaps upgrading the dialogue system and implementing those UI changes you posted were all that was necessary to fix that issue?

I put together a sample project to give you a better idea of how things are set up in my project. I will be emailing it to you momentarily.
User avatar
Tony Li
Posts: 21984
Joined: Thu Jul 18, 2013 1:27 pm

Re: Changing Dialogue UI Without Destroying Dialogue Manager Between Scenes

Post by Tony Li »

Hi,

Thanks for sending a reproduction project. Since the dialogue panels have animators and Wait For Close ticked, you need to give them time to close. I replied to your email with a suggestion that delays the scene load by 1 second. Alternatively, you could delay in a loop until the dialogue UI's isOpen property is false.
Post Reply