Loading Scene and Main Scene - unity3d

I'm building a mobile game, and my game should contain
Loading Screen with progress
Lobby screen
Game screen (with loading screen before the game loads)
No special levels in the Game...
Notice that I need to be able to share GameObjects between the scenes, for example my Network handler, which holds a connection to my servers.
How will you construct the scenes for this? What is the best practices for scenes creating?
I can thought of the following options:
Two Scenes: Loading Scene + Main Scene and share GameObjects:
The loading scene will be very lightweight scene, which will only be exists for
loading the Main Scene. It can show a progress bar according to the
progress of the main scene loading and the network login process.
Pros: The application will be loaded fast (showing the loading scene
with the progress)
Cons: I will have to share my Network handler
between the scenes (Holding the connection after a login).
Two Scenes: Loading Scene + Main Scene without sharing the
GameObjects:
I would like to be able to start loading the main scene
async, but without switching to it automatically. I want that the
main scene will start the login process for example, and only when
finished all the initialization tasks it will notify the Loading
scene that it is ready to be switched. Is this possible? Can I load
the scene in background and actually do the switching on demand?
Also I will need to be able to get the progress from the main scene
in order to show it in the loading progress bar.
Pros: No
GameObjects sharing is required - clean and isolated code.
Cons: I'm
not sure that Unity has this ability....
One scene:
Pros: All the shared GameObjects are in one place
Cons: Very slow loading time of the application (Unless there is an
option to tell unity to ignore the loading of several GameObjects
and then I could load them during the Loading screen showing time).
Thanks!

I would have 3 different scenes (one for each screen), and switching from scene to scene with the SceneManagement.LoadScene() method of UnityEngine.SceneManagement.
To share GameObjects between scenes, and more generally to share data, you have 3 options:
use a static class: good to share values
use DontDestroyOnLoad: be careful not to have duplicate objects when using that
store/load data in a file
If you want details on how to do and the differences between these 3 solutions, I advise you this tutorial : https://www.youtube.com/watch?v=WchH-JCwVI8
It is one hour long, but very useful and complete, everything is there.

I would recommend having three different scenes for the different screens.
You might have several "menu screens" in the "menu scene".
For sharing gameobjects, you can set "DontDestroyOnLoad" on the obect you want to share. From the docs:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void Awake() {
DontDestroyOnLoad(transform.gameObject);
}
}
https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
For option 2:
I guess the scene won't switch to the main scene until it's finished loading. However, there might be a bit of a lag while it's loading, which might show if you're displaying a loading animation (a spinner, for instance).
It's also possible to use SceneManager.LoadSceneAsync, which will load the scene in the background. I haven't got personal experience with that one myself, but might be helpful to keep the loading screen updating while main screen is loading.
https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html

Related

How should I handle a multiple scenes project?

I'm trying to make this game using the approach of multiple scenes to make things more modular.
In my actual case I have an "Initialization" scene which holds some global state objects and the one to control the state machine of all the scenes in the game.
As for the other scenes, for now I divided them just in two: the base scenes (which for now contains everything besides UI) and its UI scenes (which basically have a Canvas and all the UI elements and UI-related scripts).
The confusion in my mind is simple though: as I tried to make the UI scenes as modular and independent as possible, there are a lot of points of interactions between the base scene and its UI scene.
For the sake of illustrating this question please take this problem I'm facing right now: I have camera animations that should be played as a response to user inputs to the UI (like the click of a button should trigger a specific camera animation). Thing is: that camera is not in the UI scene. The way I'm resolving this problem right now is creating a ScriptableObject which holds events for important actions triggered in the UI scene that are fired in the UI scene and subscribed in any other place. The same can occur in the opposite direction: the UI scene need to react to many actions that happens in other scenes.
Considering that the "camera animation" problem I explained above can happen with many other objects, if there is not a better way to handle that wouldn't splitting a game into multiple scenes be just too much of work just for the benefit of modularity? And by that I also asks: am I handling this problem the right way?
If you want to keep things consistent between scenes, there are a few ways to do it.
PlayerPrefs lets you keep variables consistent, I don't need to do a whole tutorial here, look it up.
DontDestroyOnLoad lets you take an object and make it consistent throughout the whole game. If you want, you can use DontDestroyOnLoad on one of your cameras and just delete the others in the other scenes if you want to keep a consistent camera.

how to switch between loaded scenes

I am new to unity and working on a projects.
I want to work with multiple scenes.
some of my scenes are like option menu in the game.
from my main screen I want to open an options scene and when I am done I want to move back to my main scene and when I am back I want to keep the things done in main scene before the options scene opens
I can change scenes with SceneManager but it loads the screen as new as if I did nothing there
is it possible to switch between loaded scenes without loading again? I think that if it is; I can continue from the progress in the main scene
if it is not how can I continue my progress (do I have to keep all the data and when the scene starts load back from that data? )
The SceneManager class provides lots of useful ways to manage your scenes. You can find documentation here.
Using multiple scenes to separate your logic is a great approach, and using the LoadSceneMode.Additive option when loading a new scene lets you load one scene alongside another.
To achieve what you want, you'd roughly need to do the following:
Load your main menu scene.
Load your options scene additively with a call like SceneManager.LoadScene("path/to/options/scene.unity", LoadSceneMode.additive).
Pass input control to your other scene.
Unload the options scene when you are finished with it.
The main menu scene will have been loaded for the entire time, and you won't have to "remember" any values or use DontDestroyOnLoad.
An alternative option is to house all of your menu functionality in a single scene, and switch between multiple canvases. You can find information about that here.
you can create a class with values that you want to keep and put it on a gameobject
and use DontDestroyOnLoad(this.gameObject); so the object won't be removed when you load a new scene

When to use scene or panel

I just have a question and I don't know exactly what to type on google.
I am making a game which is always instantiating scenes now on my login process I am trying to login wrong account so there should be something that needs to pop up like an error message
Now my question is . Is there going to be a problem when I build this up because there's a tons of them or it is just normal?
But basically when i try to input the correct id and password this scenes will be deleted.
There shouldn't be a problem but this looks like an abuse of scene to me. You have too many unnecessary scenes.
Here is when you need to create or use a new scene:
1.Main Menu
This is the first scene that loads. By separating it with your game scene, you will increase loading time.
2.Game Levels
The levels in your game requires scene for each one. This makes loading them faster. You can also separate one scene into multiple ones if it's really a big scene. This also increases the speed of loading time.
You do not need scene for other things you have in your question. Those should be a UI Panels. You can create a panel by going to the GameObject ---> UI --> Panel menu. It's really easy to show/hide a panel.
For example, you have login and emergency panels:
public GameObject loginPanel;
public GameObject emergencyPanel;
to show the login panel, you disable or deactivate the emergency panel first then activate the login panel:
emergencyPanel.SetActive(false);
loginPanel.SetActive(true);
That's all you have to do.

Best way to switch UI in Unity3D

We are building a mobile app built in Unity3D, which involves a lot of UI switch. For example, from this page to the other page, it involves a lot of disabling the previous UI and activate new UI elements.
A common way to do is to set old UI inactive and new UI active. When switch back, just deactive/active again. But I read that this will cuase Rebuild problem (Canvas.SendWillRenderCanvases or BuildBatch). I wonder what is the alternative?
Will these two solutions work?
Instead of activate/deactivate UI element, apply it on the UI canvas.
Deactivae the UI element by moving it far away. Will it cause UI Rect rebuild?
Set in different layer, change its layer to invisbile layer when deactivate.
I would discourage you from using a state machine for your UI if you consider developing an application with many UI layers.
It will result in a scene hierarchy with hundreds of objects, some of them only been used when going deep down the app (like settings of a specific page) but they end up in memory at all time.
Also, it makes things harder to debug since you cannot really jump to a specific state without going through all the previous ones (except if you are already advanced prog and you defined your classes so they can work from anywhere).
The easy solution is to use scenes to separate your states, just like it is done in Android/iOS with Activity/Fragments or views.
This will clean you memory when needed, you can still keep scenes alive on the stack (like mobile OS does) using additive scene loading, since you won't have a lot of objects to create, the scene changes will seem seamless.
You can easily reuse code over scenes with inheritance and extension with scene name:
public class MyUIClassWithManyCommonCode:MonoBehaviour{}
public class FrontPage : MyUIClassWithManyCommonCode{}
public class CatalogPage : MyUIClassWithManyCommonCode{}
And finally since, you limit the amount of objects in a scene to only what should be seen, it is easy to find an object in the scene.

Is it more efficient to change scenes in Unity or to have different ui screens?

I've been working on a really simple game for iOS that has just three scenes; the start scene, game scene, and game over scene. I was running the game and analyzing performance with the profiler and I noticed that when I changed scenes, which utilized the "SceneManager.LoadLevelAsync()" function, the CPU usage was around 90%. This is only for less than a second of course, and then the CPU usage drops again and I get around 70-80 fps, but this got me wondering if it would be more efficient for a simple game like this for me to simply have several UI "screens" (basically just a group of objects that I can activate and inactivate), which is what I did with my pause screen (it is just an overlay).
Of course this could have difficulties of its own, like I would have to restart the game on the same scene but it might help me with my problem of running the mute function I've built on my music manager, which is instantiated in the start scene, from a button that is on my game scene, and I wouldn't have to use the "DontDestroyOnLoad()" function on the music manager or my score manager (which stores the score to be displayed on the game over scene). But would it be inefficient to have so many inactivated objects, or is Unity pretty good at managing things like that?
In my personal opinon, menu system should be in one scene.
Having different scenes for every menu screen will cause overhead. Even it is for few micro seconds it will affect user experience when navigating between menus frequently. This is because of loading and destroying of each UI gameObject in scene.
While menu system based in one scene requires only activating and deactivating of gameobjects instead of instantiating and destroying.
You can have one root object for menu and assign it a canvas component and then you can add different panels for each screen and assign them canvas groups to toggle them on and off smoothly.
Here is a good tutorial for creating menu system: https://www.youtube.com/watch?v=DNqTUwnpLvI
Hope this helps.
You are correct, If your game / app is small you should keep it as simple as possible, if the only difference between your scenes is just UI & your "in game" scene is not that big, you can for sure keep using the same scene and have the UI activate/deactivate.
*Inactive objects DO eat memory.