Why is PostProcessScene called after Awake in editor?

Why is OnPostprocessScene called after Awake for scene objects when starting a play session in editor? Shouldn’t it be before Awake? This behaviour is present in Unity 4.6.6p3 and 5.1.1f1.

I wanted to improve this nested prefab script to handle also objects that are not in scene, e.g. instantiate hierarchy of prefabs in Awake. The prefab is instantiated in OnPostprocessScene and attached to a parent. I wanted to set a reference to the instantiated child to indicate that prefab doesn’t need to be instantiated again once Awake is called for the first time.

Here’s a simple test code and log

 public class PrefabInstance : MonoBehaviour
	[SerializeField] private GameObject _prefab;
	[SerializeField] private GameObject _prefabInstance;
	void Awake()
		Debug.Log("PrefabInstance.Awake() instance null? " + (_prefabInstance == null));
	void OnEnable ()
		Debug.Log("PrefabInstance.OnEnable " + name);
	public static void OnPostprocessScene() 
		foreach (PrefabInstance pi in UnityEngine.Object.FindObjectsOfType (typeof (PrefabInstance)))
			GameObject go = GameObject.Instantiate(pi._prefab) as GameObject;
			pi._prefabInstance = go;
			go.transform.parent = pi.transform;


More on PostProcessScene behaviour:

  • When building/exporting as standalone, OnPostprocessScene is called twice, no Awake. Both post process apparently act on two different scenes since adding "Debug.Log(“OnPostprocessScene() - " + pi.transform.childCount);” in the foreach loop above, report child count of 1 twice. UPDATE: This is a confirmed bug. Unity Issue Tracker - PostProcessScene called twice during a build
  • When launching the standalone there’s only Awake and OnEnable calls as expected. Verified by logging that the Loader object has only one child.

First, it’s important to note that Awake() and OnEnable() are called immediately, in that order, whenever any object is instantiated. With that in mind, understanding this behavior is just a matter of noting that when building a scene, Unity first instantiates all of the objects in it, and then runs any post processing callbacks. If it didn’t instantiate the objects first, there would be nothing for the post processing callbacks to operate on since scenes are built in a vacuum so as not to affect the original scene file/asset. It’s also worth noting that in playmode, scenes are apparently built on the fly, so every time Application.loadLevel or one of its derivatives is called, OnPostprocessScene will be run again.

Anyway, all this is to say that any code that needs to be run after OnPostprocessScene needs to go in Start().