- Home /
Singleton instance accessed in coroutine always null
I have two singleton objects: one which managers the user data, and another which manages Goal/mission data. In order to keep the code organized, I wanted to handle loading saved data, etc through the User script. However, whenever the user instance accesses the GoalDatabase script in it's Awake, the latter's static instance is always seen as null.
I set the user class up as follows:
public class User:MonoBehaviour
{
public static User userInstance;
void Awake()
{
//setup instance if this is the only copy
if (userInstance == null)
{
/*Setup this instance*/
DontDestroyOnLoad (this.gameObject);
userInstance = this;
/*Load the saved user data*/
bool ReturningUser = this.LoadData();
/*Load or import goal data*/
StartCoroutine("SetGoalData",ReturningUser);
}
else if (userInstance != this)
{
Destroy(this.gameObject);
}
}
public IEnumerator SetGoalData(bool returningUser)
{
Debug.Log ("In SetGoalData coRoutine and ReturningUser:" + returningUser.ToString());
//wait for Goal Database object to instantiate
while (GoalDatabase._instance == null)
{
Debug.Log ("-Goal instance null-");
yield return null;
}
//if returning user, load serialized goals data, else load goals excel data
if(returningUser)
{
Debug.Log ("-In SetGoalData before LoadData()-");
GoalDatabase._instance.LoadData();
}
else
{
Debug.Log ("-In SetGoalData before ImportData()-");
GoalDatabase._instance.ImportData();
}
}
//etc... }
Similarly, I set up the GoalDatabase Singleton like this:
public class GoalDatabase : MonoBehaviour {
public static GoalDatabase _instance;
void Awake()
{
Debug.Log ("In GoalDatabase Awake()");
if (_instance == null)
{
Debug.Log ("Instance was null");
/*Setup this instance*/
DontDestroyOnLoad (this.gameObject);
_instance = this;
}
else if (_instance != this)
{
Destroy(this.gameObject);
}
// if (_instance == null)
// {
// Debug.Log ("At end of GoalDatabase Awake(). _instance is still null");
// }
// else
// {
// Debug.Log("==========AT END OF GOALDATABASE Awake(). _instance IS NOT NULL==========");
// }
}
It seems like the coroutine should wait until the GoalDatabase instance is set, then everything should be in line. BUT the GoalDatabase reference, as the coroutine sees it, is ALWAYS NULL. I am especially baffled, because the debug statements in the GoalDatabase (currently shown as commented out) indicate that it is in fact not null. What am I missing? Thanks for the help.
Edit: both these scripts are attached to a game object in the scene (separate GOs).
Answer by Xtro · Jun 04, 2014 at 08:07 PM
I copy pasted your code to a fresh new project. There is no problem. It's working as expected. I ofcourse had to disable some lines to be able to copile it. Here is my version of your code. Put it in a fresh new project and test.
using UnityEngine;
using System.Collections;
public class User : MonoBehaviour
{
public static User userInstance;
void Awake()
{
Debug.Log("In User Awake()");
//setup instance if this is the only copy
if (userInstance == null)
{
/*Setup this instance*/
DontDestroyOnLoad(this.gameObject);
userInstance = this;
/*Load the saved user data*/
bool ReturningUser = true;// this.LoadData();
/*Load or import goal data*/
StartCoroutine("SetGoalData", ReturningUser);
}
else if (userInstance != this)
{
Destroy(this.gameObject);
}
}
public IEnumerator SetGoalData(bool returningUser)
{
Debug.Log("In SetGoalData coRoutine and ReturningUser:" + returningUser.ToString());
//wait for Goal Database object to instantiate
while (GoalDatabase._instance == null)
{
Debug.Log("-Goal instance null-");
yield return null;
}
//if returning user, load serialized goals data, else load goals excel data
if (returningUser)
{
Debug.Log("-In SetGoalData before LoadData()-");
//GoalDatabase._instance.LoadData();
}
else
{
Debug.Log("-In SetGoalData before ImportData()-");
//GoalDatabase._instance.ImportData();
}
}
}
using UnityEngine;
using System.Collections;
public class GoalDatabase : MonoBehaviour
{
public static GoalDatabase _instance;
void Awake()
{
Debug.Log("In GoalDatabase Awake()");
if (_instance == null)
{
Debug.Log("Instance was null");
/*Setup this instance*/
DontDestroyOnLoad(this.gameObject);
_instance = this;
}
else if (_instance != this)
{
Destroy(this.gameObject);
}
if (_instance == null)
{
Debug.Log ("At end of GoalDatabase Awake(). _instance is still null");
}
else
{
Debug.Log("==========AT END OF GOALDATABASE Awake(). _instance IS NOT NULL==========");
}
}
}
I had another another copy of the script inside the Editor folder (copied and pasted ins$$anonymous$$d of cut and paste on accident) and I think that was causing the issue (confusion of static instances?). When I removed the extra script it worked.
Thanks for the help though.
Your answer
Follow this Question
Related Questions
Avoid NullReferenceException with Singleton 3 Answers
Instantiating a Coroutine? 2 Answers
Would setting this static cause a memory leak? 1 Answer
Playmode script recompilation - static vars lost? 0 Answers
Static reference cost 1 Answer