I have a prefab “SceneCommon” with stuff that’s common to every scene.
There’s one of these prefabs in every scene. It has the Camera, some managers, Canvases - nothing too special.
I’d like to convert the SceneCommon to a DontDestroyOnLoad when I enter Play for the first time.
The problem is that when I load a second scene during Play, there’s a SceneCommon there.
I don’t want to remove it because I want any scene to be playable.
I also don’t want to instantiate the prefab instead of it already existing in the scene because I can’t lose the camera and some other stuff
The various managers do things in Awake().
My proposed solution is: DestroyImmediate.
I know, huge caveats to using this, but unless I’m mistaken it should work in this situation. I have a script with an early DefaultExecutionOrder on the prefab, which in Awake checks to see if there’s already a SceneCommon (singleton) and destroys itself if so.
The result is that none of the second scene’s SceneCommon or its children have an Awake()/Enable()/Disable() or even Destroy() called. The managers on the now-destroyed SceneCommon never have their Awake() called.
As a result, when I load the second scene, the scene’s existing SceneCommon is immediately destroyed and I should be able to go on my merry way using the DontDestroyOnLoad’d SceneCommon.
My only caveat is to make sure you never reach the end of a frame with no camera present.
The reason is that on certain targets (like iOS and Android) this may introduce a frame of “glitchy noise” graphics, or perhaps a bright flash.
ALSO I don’t think there’s any actual prohibition against DestroyImmediate. It just will tend to surprise a lot of people when you do it, but sometimes it is necessary. Destroy() doesn’t happen until all Update()s are over with.
For instance, if I want to CreatePrimitive() a Cube but I want to remove the BoxCollider and add a BoxCollider2D immediately, I cannot add the BoxCollider2D because it clashes with the BoxCollider, which even if I Destroy() it first, it still hangs around until end of the Update()s, preventing me from adding the BoxCollider2D.
I’m not sure, but are you making the Matrix? And you want the construct to always exist?
DontDestroyOnLoad() prevents anything that, that main object has in it’s children(hierarchy) from being deleted each scene. So if you made a “Main” object, with a Main.cs script, that declares DontDestroyOnLoad(). And have Directional Light, Main Camera, and whatever else childed to that, if you want to carry them through scenes? problem solved.
But if you want to always have a main scene loaded, then look into SceneLoad.additively(or however it’s written out). That way any extra scenes you run, can just be un-loaded, and you’ll go back to that main scene with everything still there.
However, if you just don’t like that new scenes get made without a camera and other stuff, and don’t really need a main scene to stay alive, then my mention on DontDestroyOnLoad() fixes that. Or worst case, you can always make a “setup” script that adds a new camera, directional light, etc…