Search Unity

Canvas (for Dialogue) gets Destroyed When Loading Into the Scene

Discussion in 'UGUI & TextMesh Pro' started by extinctionx525, May 18, 2020.

  1. extinctionx525

    extinctionx525

    Joined:
    May 18, 2020
    Posts:
    1
    Hello! I am very beginner, following a YouTube tutorial to make an RPG style 2D game. I am at the point where I have created an NPC with dialogue. The dialogue works as it should if I load directly into that scene and play. However, if I start from my spawn scene and then load into that scene, the Canvas for the dialogue keeps getting destroyed for some reason and when I interact with the NPC it says that the GameObject has been destroyed.

    Attached is my script for the UIManager that is attached to my player HUD as well as the Canvas for the dialogue NPC. No idea what to do.. if I null the


    if (!UIExists)
    {
    UIExists = true;
    DontDestroyOnLoad(transform.gameObject);
    }
    else
    {
    Destroy(gameObject);

    }

    then the dialogue works when I load into the new scene, however my HUD is reproduced over the HUD from the previous scene when I load into the new one. I am so lost with this!! I dont know why it keeps getting destroyed and only works if I start playing on that scene.

    Thank you!
     

    Attached Files:

  2. Derekloffin

    Derekloffin

    Joined:
    Mar 14, 2018
    Posts:
    322
    It is hard to tell from what is given here. However, honestly, from what you're describing, I'd recommend against this approach in the first place. It is likely better to make a prefab for your dialog UI and spawn it dynamically as needed rather than trying to manage UI elements that are kept around perpetually. For instance I have inventory, building and crafting menus that all function in this manner.

    Now, looking at this approach, I suspect the issue is the difference in what you're telling Unity to keep and what you're telling it to destroy. You're telling it to keep transform.gameobject, which is the master gameobject, but you're telling it to destroy just gameobject which is the monobehavior, not the master gameobject that behavior is attached to. I would look to that as the source of the problem.
     
  3. pronline

    pronline

    Joined:
    Jun 13, 2017
    Posts:
    5
    I have ran into the same issue while following a book that was written 6yrs ago (and obviously an older version of unity that "may" have allowed for this).

    * A canvas is made with panel (renamed to dialog) and image/text fields attached.
    * Then, a messaging manager is created as a singleton with dont destroy - a subscriber method is included to allow messaging broardcast / reciever along with a conversation manager to make use of the 'dialog' to show conversations with a npc.

    heres where the trouble begins..

    the dialog is destroyed when leaving the scene and recreated in a 2nd scene (if you use a ui prefab). if you dont approach the npc, you have no issue travelling between scenes.

    If you do approach the npc a subscriber is made and conversation starts - from what I can see is that the subscriber is made, conversation is handled, but there is no explicit use of unsubscribe or clear subscribers. As the subscriber (in a messaging manager singleton) is still referencing destroyed objects when you load a new scene it just keeps throwing exceptions..

    MissingReferenceException: The object of type 'CanvasGroup' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    ConversationManager.OnGUI () (at Assets/Scripts/ConversationManager.cs:61)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr, Boolean&)

    Now as the book (mastering unity 2d game development (2016)) will have copywrite, I can not share its code, only try to explain where the issue lies from what I understand as a beginner with unity that has never got past those silly YouTube videos that you cant learn from.

    I also assume the video that the op was watching is an older video with content based on knowledge the youtuber learned from such a book or a methodology commonly used at the time...
     
  4. gooby429

    gooby429

    Joined:
    Aug 13, 2019
    Posts:
    136
    are you using fast enter playmode options? you might just need to reset the UIExists to false in Awake or OnDestroy
     
  5. pronline

    pronline

    Joined:
    Jun 13, 2017
    Posts:
    5
    Update:

    So looking at the error that indicates Assets/Scripts/ConversationManager.cs > OnGUI at line 61 > dialogBox is referenced (our dialog in UI).

    rather than accessing methods for our dialog box (which may not be there), eg: dialogBox.alpha = 1
    instead, encapsulate all code within OnGUI with:

    Code (csharp):
    1.  
    2. void OnGUI()
    3.     {
    4.         if (dialogBox != null)
    5.         {
    6.              // Original code that was in OnGUI
    7.         }
    8.     }
    9.  
    While this may fix the issue of referencing destroyed objects from another scene within a singleton causing an exception, it may not be 100% correct - remember the singleton is adding subscribers an may not be cleaning up after itself..

    A step in the right direction, but more investigation on subscribers is needed.. Hope this is of help to anyone suffering this or a similar issue - at least it gives an idea on what things to look at.
     
  6. pronline

    pronline

    Joined:
    Jun 13, 2017
    Posts:
    5
    fast enter play mode? please elaborate (im a newbie too.. ;) )..
    I am running test from within unity, not from a build if thats what you mean..

    Ill look through the many scripts for UIExists (dont remember seeing that) - the singleton messaging manager certainly doesn't have it..

    While I have a solution for stopping the exception, Im not sure if it fixes the subscriber count (weather it unsubscribes). Im going to have to Debug.Log subscribers to see if I need to modify something else for this code to work without stacking wastr resources..
     
  7. pronline

    pronline

    Joined:
    Jun 13, 2017
    Posts:
    5
    Using:
    Subscribe
    Debug.Log("Subscribe. No. of subscribers = "+subscribers.Count);

    Unsubscribe
    Debug.Log("Unsubscribe. No. of subscribers = "+subscribers.Count);

    On testing I see that subscribers are added for character and npc (2 of) and leaving to another scene unsubscribe is called twice (0 subscribers). However, in the 2nd scene theres no subscribers registered - not even the player character. Returning to the 1st scene, both character and npc are registered (2 of).

    What I do see is the singleton it started in the 1st scene each time (as I have a debug log to tell me), but in the 2nd scene theres no log to say its started.. That is confusing me a little..

    Code (csharp):
    1.  
    2. //Static singleton property
    3.     public static MessagingManager Instance{get; private set;}
    4.  
     
  8. pronline

    pronline

    Joined:
    Jun 13, 2017
    Posts:
    5
    Update:

    Nothing is wrong with messaging manager. I forgot to add an empty to scene2 with the script attached - a senior moment!!

    So yes, Investigating the error message and taking the necessary action will save the day...