Search Unity

GameObject can't be found in DontDestroyOnLoad Hierarchy

Discussion in 'Scripting' started by gustavopinent, Aug 7, 2019.

  1. gustavopinent

    gustavopinent

    Joined:
    Jan 14, 2019
    Posts:
    38
    I have this GameObject 'GameManager' that is loaded with DontDestroyOnLoad directive. It will stay in hierarchy like this:


    The GameManager code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class GameManager : MonoBehaviour
    8. {
    9.     public static GameManager gm = null;
    10.  
    11.     public string lang; // idioma / language
    12.     public string[] LangCodes = new string[] { "pt", "en" }; // códigos / codes
    13.     public string[] LangLabels = new string[] { "Português", "English" }; // etiquetas / labels
    14.     public TextAsset Texts;
    15.     public float loadingTimeout = 5f;
    16.     public GameObject IniImage;
    17.  
    18.     private Controle controle;
    19.  
    20.     private void Awake()
    21.     {
    22.         if (gm == null) gm = this;
    23.         else if (gm != this) Destroy(gameObject);
    24.  
    25.         DontDestroyOnLoad(gameObject);
    26.  
    27.         controle = GameObject.Find("nave-resgate").GetComponent<Controle>();
    28.         if (!controle) print("GameManager ini ERROR 'controle' not found");
    29.         else StartCoroutine(IniAfterLoaded());
    30.     }
    31.  
    32.     private IEnumerator IniAfterLoaded()
    33.     {
    34.         yield return new WaitForSeconds(0.05f);
    35.         string res = "?";
    36.         float start = Time.time;
    37.         bool loaded = false;
    38.         while (!loaded && (Time.time - start) < loadingTimeout)
    39.         {
    40.             loaded = GameObject.Find("Main Camera").GetComponent<Loader>().loaded;
    41.         }
    42.         res = (loaded) ? Initalize() : "GameManager ini ERROR Scene loading timeup";
    43.         if (res != "OK")
    44.         {
    45.             print("GameManager ini ERROR: " + res);
    46.         }
    47.     }
    48.  
    49.     private string Initalize()
    50.     {
    51.         IniImage.SetActive(false);
    52.         controle.Ini("ini");
    53.         //ChangeState("ini");
    54.         return "OK";
    55.     }
    56.  
    57.     public void Reload()
    58.     {
    59.         SceneManager.LoadScene(0);
    60.         StartCoroutine(IniAfterLoaded());
    61.     }
    62.  
    63.     /*public void ChangeState(string newState)
    64.     {
    65.         print("GameManager controle: " + controle);
    66.         print("GameManager ChangeState to " + newState);
    67.         if (Global.ea == "ini")
    68.             controle.Ini(newState);
    69.     }*/
    70. }
    71.  
    So after make sure is all load, it calls initialization of the game, witch instantiates a prefab of a window in Canvas. This window called JanTitulo got buttons and a Dropdown menu, this is the script code of this window:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class JanTitulo : MonoBehaviour
    8. {
    9.     //public GameObject goGameManager;
    10.  
    11.     private GameManager gameManager;
    12.     private Controle controle;
    13.  
    14.     private void Awake()
    15.     {
    16.         controle = GameObject.Find("nave-resgate").GetComponent<Controle>();
    17.         gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
    18.         print("gameManager: " + gameManager);
    19.         var btnIni = this.gameObject.transform.Find("btnIni");
    20.         btnIni.GetComponent<Button>().onClick.AddListener(() => { IniGame(); });
    21.         var btnOpt = this.gameObject.transform.Find("btnOpt");
    22.         btnOpt.GetComponent<Button>().onClick.AddListener(() => { Options(); });
    23.         var btnInstr = this.gameObject.transform.Find("btnInstr");
    24.         btnInstr.GetComponent<Button>().onClick.AddListener(() => { Instructions(); });
    25.         var dropDown = this.gameObject.transform.Find("Dropdown");
    26.         dropDown.GetComponent<Dropdown>().onValueChanged.AddListener(ChangeLanguage);
    27.     }
    28.  
    29.     private void IniGame()
    30.     {
    31.         controle.Ini("play");
    32.     }
    33.  
    34.     private void Options()
    35.     {
    36.         controle.Janela("Opcoes");
    37.     }
    38.  
    39.     private void Instructions()
    40.     {
    41.         controle.Janela("Instrucoes1");
    42.     }
    43.  
    44.     private void ChangeLanguage(int sel)
    45.     {
    46.         gameManager.lang = gameManager.LangCodes[sel];
    47.         gameManager.Reload();
    48.     }
    49. }
    50.  
    But at start of the game, the window is in the screen and the following error appears:
    NullReferenceException: Object reference not set to an instance of an object
    JanTitulo.Awake () (at Assets/Scripts/JanTitulo.cs:17)

    The line is precisely the gameManager definition, it is not finding 'GameManager' in hierarchy as long I can see it there. I am dealing with this error for hours, I tried to put it in by editor as can be seen in the line 'public GameObject goGameManager;', however this will generate another error because it will call the script from the prefab instead the instance.

    How can I find the GameManager instance that is in active in hierarchy???
     
  2. https://docs.unity3d.com/ScriptReference/GameObject.Find.html

    GameObject.Find is looking for the name of the game object. According to your screenshot your game object's name is "GameManager(Clone)". You're looking for "GameManager".
     
  3. gustavopinent

    gustavopinent

    Joined:
    Jan 14, 2019
    Posts:
    38
    First of all, thank you for solving my problem!
    Second, that was the most stranger situation I ever saw! I am not a great programmer, but I have seen about programming since the 80's, and I didn't see all, as it seems. The 'Clone' between parenthesis should not be a name of something ever, you should not use parenthesis for names in any language since Fortran, Cobol, Basic etc.. To me the 'Clone' expression was just to point that it was actually a clone from a prefab. The instance name might be the same or enumerated if multiply clones are made... anyway, I really don't like Unity! It has been the most painful learning process for me ever, difficulties in every step of the way, not a single day of peace!
    Third, and last, sorry you have to hear this, please keep helping people and forget about this grumpy old man!
     
  4. I started with C64 Basic and later Cobol, dBase III and those things. But I adapted to the newer things later, you can do it too. Don't give up learning!

    It's a game object, not an instance. The name is just a string in memory, it can be anything (almost). You also can set to whatever you like. You're the developer, take care of it.

    Well, then you're at the wrong place, my friend. :)

    Game making is like that, you can get used to it and take up the battle or you can run. It's your choice. I hope you decide to stay and learn instead of running though.
     
    TankThunderbird likes this.