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.

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

}