- Home /
FindObjectOfType won't find object that hasn't had "Awake" called?
Hi,
I'm using the following pattern to find a singleton object that I have placed in the scene myself.
public class Program: MonoBehaviour { private static Program s_Instance;
...
public static Program Instance
{
get
{
if (s_Instance == null)
{
UnityEngine.Object program = FindObjectOfType(typeof(Program));
if (program == null)
Debug.LogError("No instance of Program detected.");
else
{
s_Instance = (Program)program;
}
}
return s_Instance;
}
}
protected override void Awake()
{
base.Awake();
if (!IsValid)
return;
if (s_Instance != null && s_Instance != this)
Debug.LogError("Multiple instances of Program detected.");
s_Instance = this;
...
}
}
There is another script which references the singleton, and a GameOBject with this script is also present in the scene.
class GameScreen {
void Awake()
{
if (Program.Instance.Game != null)
OnGameStarted();
Program.Instance.GameStarted.Register(this);
}
}
The error I get (sometimes) is:
No instance of Program detected.
UnityEngine.Debug:LogError(Object)
Program:get_Instance() (at Assets\App\Scripts\Program.cs:63)
GameScreen:Awake() (at Assets\App\Scripts\Game\GameScreen.cs:22)
I'm thinking it may be because FindObjectOfType does not consider objects in the scene that have not been "awakened" yet. Is this the case? The documentation of Awake seems to contradict this behaviour:
Awake is called after all objects are initialized so you can safely speak to other objects or query them using eg. GameObject.FindWithTag
Edit: I should add that I am aware that interacting with an object that may not have been "awakened" is a bad idea and I have moved the GameScreen.Awake code into Start. Just curious why it wasn't working as expected.
Answer by Tetrad · Jul 11, 2010 at 08:11 PM
The order of Awake
is non-deterministic, so right off the bat you shouldn't rely on that. You should change all singleton-accessing startup stuff to Start
.
Also, since Awake is called as soon as the object is instantiated, you can save yourself some headache and just set your static instance pointer in awake itself, i.e.
static ClassName instance; public static ClassName Instance { get { return instance; } }
protected override void Awake() { if( instance != null ) { // error condition in the event you want to actually prohibit more than one instance of this object. } instance = this; // etc
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613064408im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
leaving level 1 Answer
Start() being called more than Once?!? 3 Answers
Awake() is not called automatically by Unity on targets reference 1 Answer
have an enemy change position on the y axis when awake (2d platformer) 0 Answers
How to mock or skip execution of Awake in playmode unit tests? 2 Answers