Where to allocate class fields in a MonoBehaviour ?

Simple question here - where do you usually allocate class fields in a typical script inheriting from MonoBehaviour (MB) ? Here are few options:

1. Directly in declaration:

public class GameSessionManager : MonoBehaviour {

    public GameSession gameSession = new GameSession();

    // ...
}

From a programmer’s perspective this is not the best choice, I would rather do it in a constructor, but I am not so sure. However this exact scenario that only covers allocating heap memory with new operator might be an exception and I could do it in MB constructor just fine.

2. Inside Awake() method:

public class GameSessionManager : MonoBehaviour {

    public GameSession gameSession

    void Awake() {
         gameSession = new GameSession();

         // ...
    }

    // ...
}

this might easily cause troubles when other MB scripts want to set up their shortcut pointers to gameSession object in Awake methods because the order of Awake() calls between scripts is arbitrary. Example, calls in order:

// 1. shortcut creation inside Awake of some SomeScript
gs = GameObject.Find("Control").GetComponent("GameSessionManager").gameSession;

// 2. allocation inside Awake of GameSessionManager
gameSession = new GameSession();

// 3. sometime later in SomeScript, causes Exception since this pointer is no longer valid
int currentScore = gs.score;

3. The third option I can think of is to make it in both Awake() and Start(). I’ll just make sure that Awake only covers allocation and Start only covers setting up shortcut pointers, but I feel adding this kind of “hidden logic” to the code is wrong as well.

What do you think, how do you usually do this ?

It seems like option 3 would be best here. Use Awake() as basically the constructor where you set up the object itself, and Start() as a way to set up references between objects, now that you know that everything is ready.

Another option that might offend your programmer sensibilities, is to make that gameSession variable static. Yes, there’s something to be said for strong coding standards and principles and following design patterns. However, there’s also something nice about easy, readable code and simplicity. If there’s ever only one game session active at a time, having a static variable makes everything so easy.