Glad you asked… going this route definitely requires slightly-higher awareness of what scene is what.
In no particular order, responding to you questions,
-
When the game or level is over, I try to go to a fresh “end level” scene (not additively!) and clear everything else out (except overall ongoing game manager obviously, as a singleton)
-
when the game gets paused I stop time and bring up a pause scene that sorts above all else, then unload it and restart the time. OR if you quit, I just go straight to the gameover scene, which loads only itself and maybe UI (or else mainmenu)
-
I usually make the content scene (what constitutes the level) be the active scene. This lets it have custom lighting.
-
When I spawn things like bullets (or enemies), I often parent them to a bullet manager GameObject, which probably lives in the player scene. You can always change which scene a GameObject is in, if you really care.
-
when the player dies and respawns I usually unload his scene, then load it afresh. That scene has enough logic in it to look around for waypoints that might have been triggered as a result of making it to a certain point in the level, or else falls back on the default content initial spawn point
Overall your strategy above seems reasonable. The devils are often in the details, and keeping things separate makes it easier to organize things differently as your needs or priorities change during development.
ALSO: put in lots of Debug.Log() spew that says stuff like “UNABLE TO FIND PLAYER SPAWN!” so you can quickly diagnose errors during testing.
The one thing I haven’t solved yet is warnings about having multiple audio listeners at once. Depending on how long it actually takes to async load a scene, various platforms may spuriously produce this warning for a couple of frames. However, I’ve never seen a customer-facing issue about it.
The other thing to watch out for is to NEVER have zero cameras. On certain platforms like Android, this will result in a garish flash of garbage graphics. I often put a camera in my main level-loading scene and turn it off after a few frames. That’s easy to test by inserting a Debug.Break() when you start a new game and then single-stepping Unity to make sure there is always a camera each frame.