0

In my game on Unity3d I have 2 classes. One of them ActsGeneral initialize variable gameManagerScript and another Act_0 try to access it.

Class GameManager is stored in object, which exists only on the first scene. I use function DontDestroyOnLoad() to use this class on other scenes. So the only way to access variable gameManagerScript - is using function FindGameObjectWithTag. But when I start the simulation, Find don't have enought time to find gameManagerObject. And here I have the error.

Script Execution Order Settings did not helped too. Should I check if the object equals null?

Class ActsGeneral

void Awake()
{
    gameManagerObject = GameObject.FindGameObjectWithTag("GameManager");
    gameManagerScript = gameManagerObject.GetComponent<GameManager>();
}

Class Act_0

void Start()
{
    // error: Object reference not set to an instance of an object
    if (actsGeneral.gameManagerScript.currentActNumber == currentLocalActNumber)
    {
    }
}

enter image description here

Edit1

I gave Find function more time to find the object gameManagerObject, but now I still have error. All objects and component are enabled and I set up Script Execution Order Settings. But it still don't work. I just don't understand the reason of that.

void Start()
{
    StartCoroutine("StartDelay");
}

IEnumerator StartDelay()
{
    yield return new WaitForSeconds(1.5f);
    if (actsGeneral.gameManagerScript != null)
        if (actsGeneral.gameManagerScript.currentActNumber == currentLocalActNumber)
        {
            Debug.Log("222");
        }
}
Amazing User
  • 3,473
  • 10
  • 36
  • 75
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Łukasz Motyczka Jan 10 '17 at 17:49
  • if you want fast and dirty, use singleton pattern at your own risk! – Bizhan Jan 10 '17 at 17:55
  • @Bijan I don't want dirty. Maybe I shoult use a coroutine to give `Find` some time to find the object. Just want to know, what other options is possible – Amazing User Jan 10 '17 at 17:59
  • Have you tried to add a `Debug.Log( gameManagerScript )` in the ActsGeneral script and a `Debug.Log( actsGeneral.gameManagerScript)` in the Act_0 script ? – Hellium Jan 10 '17 at 18:00
  • @Hellium First `Debug.Log(actsGeneral.gameManagerScript)` give null reference exception error, then `Debug.Log(gameManagerScript)` say, the the object is exists – Amazing User Jan 10 '17 at 18:08
  • @dima : Then, you have a problem of execution order. Does the ActsGeneral script and the object holding it are enabled in the scene before you hit "play" ? – Hellium Jan 10 '17 at 18:11
  • @Hellium answered in the Edit1 – Amazing User Jan 10 '17 at 18:21
  • figure out what is null and why. use Debug.Log for that. – yes Jan 10 '17 at 19:22

1 Answers1

3

The easiest way when you try to access data from another class in a different scene is using singleton pattern.

First add this script to your proyect:

using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    /**
      Returns the instance of this singleton.
   */
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = (T)FindObjectOfType(typeof(T));

                if (instance == null)
                {
                    Debug.LogError("An instance of " + typeof(T) +
                                   " is needed in the scene, but there is none.");
                }
            }

            return instance;
        }
    }
}

Second add this to your ActsGeneral class.

    using UnityEngine;

    public class ActsGeneral : Singleton<ActsGeneral> {
    ...

And in your class Act_0 from the other scene

public class Act_0 : MonoBehaviour {

ActsGeneral ac;

..
void Start()
{
    ac = ActsGeneral.Instance;

    //Do something with ac ....
}

Remember that the GameObject with the ActsGeneral script must have a don't destroy on load property and must be in the first scene loaded.


If this doesn't work, the problem is in the Awake event of your ActsGeneral script, so you can change it for this:

void Awake()
}
    gameManagerScript = GameManager.Instance;
}

And in the GameManager script

using UnityEngine;

public class GameManager : Singleton<GameManager> {
...
Sergio Ormeño
  • 389
  • 1
  • 8