Scene Manager - Load between scenes and show a progress bar - [ Unity Tutorial ]

Sdílet
Vložit
  • čas přidán 4. 03. 2021
  • Show a progress bar to your players as a new scene loads. Loading your scenes asynchronously can help reduce the time users have to wait between levels.
    ❤️ Become a Tarobro on Patreon: / tarodev
    =========
    🔔 SUBSCRIBE: bit.ly/3eqG1Z6
    🗨️ DISCORD: / discord
    ✅ MORE TUTORIALS: / tarodev
    About Tarodev:
    Develop video games like a pro!
    Whether you're a beginner or a seasoned game developer, you'll find lots of useful tips and tricks to boost your development career. Visit the channel: / @tarodev

Komentáře • 90

  • @damjanzugic6343
    @damjanzugic6343 Před rokem +33

    By leaving the loading progress at 0.9f, Unity provides a small buffer that allows the engine to complete any final processing tasks before the scene is fully activated, which helps to prevent any frame rate drops or other issues. The reason for this is that once the scene is activated, it can cause a spike in the frame rate and introduce frame rate drops, which can be noticeable to the player and negatively impact the game experience.

  • @Krechevskoy
    @Krechevskoy Před 2 lety +4

    You just continue to provide the absolute best content for unity on here. Bravo!

  • @karma.codes_
    @karma.codes_ Před 2 lety +2

    This is what i am looking for. This tutorial solved my almost every problem

  • @arcanep
    @arcanep Před 3 lety +7

    super-useful you deserve way more subs

  • @CaioMGA
    @CaioMGA Před 2 lety

    straight to the point. great tutorial

  • @shahar.mmoshin8694
    @shahar.mmoshin8694 Před 2 lety +1

    @tarodev keep up the good work very informative tutorials!!!

  • @jitendrachauhan9837
    @jitendrachauhan9837 Před 2 lety +1

    Thank you for the good presentation.
    Absolutely very clear and to the point explanation.
    If possible, please make a video on different types of material and apply the effects on it. As you already used in your videos. or you can say tips to make the environment clear and catchy.

  • @gamedevGod
    @gamedevGod Před rokem +1

    Thank you! Great lesson!

  • @gamedevbaiyi936
    @gamedevbaiyi936 Před 2 lety +1

    Thank you man. You're so good. ✌

  • @nixon_r
    @nixon_r Před 2 lety

    Very good tut, helped a lot

  • @2rug3__12
    @2rug3__12 Před rokem

    Really cool. Thanks!

  • @LION303200
    @LION303200 Před 2 lety +5

    the target is not needed once you make fill amount 0 every time u load the scene.,, and nice work btw, plus u make it easy and pretty much explain everything needed .thanks

  • @user-uk9er5vw4c
    @user-uk9er5vw4c Před 6 měsíci

    great tutorial man

  • @322ss
    @322ss Před 3 lety +62

    That 0.9 loading thing happens when you set allowSceneActivation to false. For some reason Unity has implemented this so that 0 to 0.9 is for loading the data (which can happen pretty much instantly on a desktop PC) and 0.9 to 1 is for setting up the scene/gameobjects etc, which might take more time...

    • @Katubug
      @Katubug Před rokem

      Hi, I know this is a year old, but does this mean that if I keep allowSceneActivation to be true throughout, I can use 0 to 1 instead of to 0.9?

    • @log_zero_fox182
      @log_zero_fox182 Před rokem

      @@Katubug Yes, that's what is implied

    • @CoolModderJaydonX
      @CoolModderJaydonX Před rokem +1

      Why does that happen instantly?

    • @log_zero_fox182
      @log_zero_fox182 Před rokem

      @@CoolModderJaydonX It happens instantly because your scene does not require too much loading. If you keep "AllowSceneActivation = true", the scene will load once it reaches 1. If you turn it to false, it will stay stuck at 0.9, and wait for you to tell it "AllowSceneActivation = true".

    • @CoolModderJaydonX
      @CoolModderJaydonX Před rokem +1

      @@log_zero_fox182 I think it was even worse before because I used a while loop instead of a do-while loop, basically doing nothing to help with the loading.

  • @Bobby59452
    @Bobby59452 Před 2 lety

    thank you sir. but, i wanna ask about, can we randomly load a different loading image screen to another random stage scene?

  • @mai4584
    @mai4584 Před rokem +3

    if anyone else watching this is noticing that one frame from the last scene appearing when the next one is loaded (almost unnoticeable but annoying) - i added a delay of the time equivalent of one frame at the end after activating the new scene but before disabling the canvas holding the loading screen and that seems to have solved it. not sure if this is the best way to go about it, please tell me if there is a better one!

  • @ElvishJumpSuit
    @ElvishJumpSuit Před rokem +1

    Nice and clear……thanks!

  • @frostdash-aviation
    @frostdash-aviation Před 2 lety

    Hi, is there any way to switch to scene 0? I tried it but it ended up unloading the scene.

  • @OldM8
    @OldM8 Před 2 lety

    Yes mate ! solid content, keep it coming please, thanks, ok bye.

  • @MayurPatel-ss6zb
    @MayurPatel-ss6zb Před 4 měsíci

    Hi, not sure if I'm missing something basic but if you remove the two artificial delays the method throws a warning about not running asynchronously since there is no longer an await call?

  • @nahuelgarcia1668
    @nahuelgarcia1668 Před 2 lety

    Thanks a lot!

  • @bekogluaydin
    @bekogluaydin Před 2 lety +1

    thank u so much.

  • @sabeelm9
    @sabeelm9 Před 2 měsíci

    This is really great, just have some questions though. How are you managing your camera and event system objects between scenes? mine appears to whinge that there are multiple of event systems and audio listeners. Presumably I have to disable one, perhaps keep it persistent from the main screen? Interested to get your thoughts.

  • @RigidDecay
    @RigidDecay Před 2 lety

    How do i setup the loading screen canvas?

  • @ThirdMovieLuke
    @ThirdMovieLuke Před rokem +7

    Great Tutorial. I do feel like I have missed one important piece though. How do you manage your scenes? I added the part about how to switch to another scene but I am interested in something a bit more advanced. I would be interested in seeing a video where you create a menu for a game, then proceed to other scenes.

    • @kitsune_shinobu
      @kitsune_shinobu Před rokem

      Yep! I am having a problem with how to connect two scenes "Main Menu" and "Gameplay" to work together with all the buttons and stuff...

  • @dago6410
    @dago6410 Před rokem

    Sadly the effect on my end is "it just loads once' lol idk what am I doiing wrong

  • @ximinas
    @ximinas Před 2 lety +2

    Hey TaroDev, thanks for the awesome tutorial. I just have a quick question regarding the program. For some reason my script requires that I include the "await Task.Delay()" line else the loading canvas doesn't get enabled, which is odd because the scene takes more than 7 seconds to change after clicking the button. Do you know why this is happening? Any pointers would be helpful. Thanks!

    • @NewEarthIntegration
      @NewEarthIntegration Před 2 lety

      i AM DEALING WITH THE SAME PROBLEM

    • @wtvdonot1135
      @wtvdonot1135 Před 2 lety

      @@NewEarthIntegration I think it it is needed in the "Do" part of the script, but this is the one after the "while" that should not be there.

    • @MQNGameDev
      @MQNGameDev Před rokem

      I believe this is because the LoadScene() method is flagged as async which expects the method to await something . This is similar to the Unity coroutine which expects a yield return to occur in the coroutine. To remedy the issue, try lowering the value in the await Task.Delay() to something like 1 in the do/while loop and remove the Task.Delay(1000) he had added to slow down the transition between scenes(Since the loading scene was small resulting in a quick load time).
      You can read more about async here:
      docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

  • @bonepay
    @bonepay Před 7 měsíci

    My problem is, on play (or in build) the load bar goes to 100% in a second and then freezes when loading next scene, so async is not really working, anyone with this problem?

  • @mitchellknirnchild8285
    @mitchellknirnchild8285 Před rokem +1

    Maybe I missed it, but somehow I forgot to put using UnityEngine.SceneManagement; at the top level and without it was obviously getting errors.

  • @notagamedev5494
    @notagamedev5494 Před 3 lety +1

    Cool

  • @Ashwin_1198
    @Ashwin_1198 Před rokem +2

    If you guys get Error CS0103 : The name 'Task' does not exist in the current context
    then put this
    await System.Threading.Tasks.Task.Delay(100);

  • @felfurion8624
    @felfurion8624 Před rokem

    If you forget the f for float part of "while (scene.progress < 0.9f);" you can waste a solid 10 minutes trying to work out why the load bar is flickering, the next scene doesn't load and clicking button multiple times adds more do not destroy items! Enjoy

  • @322ss
    @322ss Před 3 lety

    Thanks for the video. Correct me if I'm wrong but 1:20 creating such singleton pattern where one calls Destroy on gameobject isn't actually going to always work how one would expect. If you call Destroy, it will destroy the object at the end of that frame, so Start and such will run on to be destroyed object (if your MB has such), unless you have some guard variable to check (wasDestroyed) to make sure that those don't run.

    • @Tarodev
      @Tarodev  Před 3 lety +2

      I just tested this by placing breakpoints in start and it never hits (v2020.3.13f1). Maybe in an older version of Unity this happened?

    • @322ss
      @322ss Před 3 lety

      @@Tarodev Maybe I've simply messed up something in my code earlier! Go figure. Anyway - great if it works!

    • @TheSxW
      @TheSxW Před rokem

      @@Tarodev it will never hit unless you add 2 objects with same script this snipped should remove the second one

  • @Davearmstrong42
    @Davearmstrong42 Před rokem

    Here is the thing... I LOVE to code. That said, I suck. I really really suck at coding. You operate at many levels above my ability.
    I know I need to know this stuff but no idea how to get from a-z...
    Like, what is an async function? So many things you assume we/I know lol
    I suppose, I will simply keep at it until your tuts make sense to me

  • @darrylwolfe7359
    @darrylwolfe7359 Před 2 lety +1

    I dont want the progress bar to load the scene once its reached 90%. I want to make the progress bar to go 100% first and when its 100%, a button appears in which the user will click it and it will then go to the scene. The progress bar looks ugly stopping at 90%. How do i make it reach at 100%?

    • @darrylwolfe7359
      @darrylwolfe7359 Před 2 lety

      nevermind. I solved it

    • @arcanep
      @arcanep Před 2 lety

      @@darrylwolfe7359 how dont just say nvm say it lmao

    • @bobbyaremyshoes2233
      @bobbyaremyshoes2233 Před 2 lety +2

      @@arcanep They probably just multiplied the progress value by "1/0.9" to scale it from (0;0.9) interval to (0;1) interval

    • @lordcailx
      @lordcailx Před rokem

      Can do it something like this code I used in a prototype project.. Sets the bar to 90% then once loading is actually 100% completed updates the bar and leaves a small delay. You'd need to add Tarodev's ActivateScene etc..
      public int sceneToLoad = 1;
      public float loadingUIDelaySecs = 0.1f;
      public void LoadLevel()
      {
      StartCoroutine(AsyncLoad(sceneToLoad, loadingUIDelaySecs));
      }
      IEnumerator AsyncLoad(int sceneIndex, float delaySecs)
      {
      yield return new WaitForSecondsRealtime(delaySecs);
      AsyncOperation operation = SceneManager.LoadSceneAsync(sceneIndex);
      Debug.Log("Async Loading Started");
      while (!operation.isDone)
      {
      float progress = operation.progress;
      Debug.Log(progress);
      UpdateSlider(progress);
      yield return null;
      }
      Debug.Log("AsyncLoad completed | SceneIndex:" + sceneIndex);
      yield return new WaitForSecondsRealtime(delaySecs);
      UpdateSlider(1f);
      //Gives the effect of 100% completion just before starting the round
      //Could use DOTween to smooth this but surely we have better things to work on (>_

  • @mrbrain3339
    @mrbrain3339 Před rokem

    Error CS0103 The name 'Task' does not exist in the current context

    • @Ashwin_1198
      @Ashwin_1198 Před rokem

      await System.Threading.Tasks.Task.Delay(100);

  • @crtus2444
    @crtus2444 Před 2 lety +1

    I love your videos. This channel is perfect. But I'm new to Unity and C# and I wanna know something. Why are you putting "_" in front of the variable names? I don't know if I expressed myself correctly?

    • @Tarodev
      @Tarodev  Před 2 lety +4

      A good naming convention can give you clear, readable code. I use _pascalCase for private variables, CamalCase for public variables and pascalCase (no underscore) for local variables. You should be able to read a snippet of code and know exactly what that variable sits.

    • @crtus2444
      @crtus2444 Před 2 lety +1

      @@Tarodev Thank you for explaining. Love your channel. Keep up the good work!

    • @ironbard4901
      @ironbard4901 Před 2 lety +1

      @@Tarodev This is excellent, I'm adopting this convention immediately.
      I noticed you underscored the _Scripts folder aswell - but I don't see how the same logic would apply there?
      Wait a minute... I vaguely remember something about underscore prefixed folders appearing higher in the hierarchy? Is that right?
      I tried to look it up, but it seems my search-fu isn't up to the task.

    • @Tarodev
      @Tarodev  Před 2 lety +2

      @@ironbard4901 Yup, that's why I do it :) It's by far my most accessed folder!

  • @risingforce9648
    @risingforce9648 Před 7 měsíci

    How to change the scene, keepint the UI elements that a singleton class need? I mean , I hate to use Singleton ,one of the reason , When you change scenes, all objects from the previous scene are destroyed and new objects are created for the current scene. However, if you have an object with a Singleton that is not destroyed (using DontDestroyOnLoad), any references to scene-specific objects in that Singleton will still point to the previous scene's objects, which no longer exist.
    For example, if your ScoreManager has a reference to a Text to display the score, this reference will be valid in the scene where the ScoreManager was created. But when changing scenes, that Text reference will no longer be valid, because that specific Text object no longer exists in the new scene.

  • @nononon8641
    @nononon8641 Před 2 lety

    public async void LoadScene (string 3008) {
    _target = 0;
    _progressBar.fillAmount = 0;
    On the first line I'm getting the following errors:
    error CS1001: Identifier expected
    error CS1003: Syntax error, ',' expected
    And I have no idea why this is happening

    • @Tarodev
      @Tarodev  Před 2 lety

      Variable names cannot start with a number. 3008

    • @nononon8641
      @nononon8641 Před 2 lety +1

      @@Tarodev Hey friend! Its me again, ur tutorial is amazing, I learned alot!! Thank you so much, and continue this amazing work!
      Cheers from Brazil!

  • @BNuwan123
    @BNuwan123 Před 3 lety

    Does singleton approach work when we have several different level with a main menu...

    • @themaskyyt
      @themaskyyt Před 3 lety +2

      Yes, you would have to create a "loading screen caller" (a script that calls the singleton), and add it to all of your scenes. That way, you could have your main loading screen script on, let's say on your main menu, and once you load a different scene, you would be able to call that loading screen, since there's a script on that scene that calls it. Another approach could be using Game Events.

  • @mohokhachai
    @mohokhachai Před 10 měsíci

    Build how to make editable at runtime

  • @ravenskin2806
    @ravenskin2806 Před 2 lety +2

    Idk why but unity wont recognize the word Task after the await :/

    • @ravenskin2806
      @ravenskin2806 Před 2 lety +1

      Nevermind ! I just forget the System.Threading.Tasks namespace !Ahah

    • @Tarodev
      @Tarodev  Před 2 lety +4

      Add 'using System.Threading.Tasks;' to the top of your file.

  • @larryd9577
    @larryd9577 Před 2 lety +2

    Instead a do while loop, we could loop as long the scene is not yet loaded. Unity uploaded a video of doing this way: czcams.com/video/zObWVOv1GlE/video.html

  • @blazingpotato642
    @blazingpotato642 Před rokem

    You can set the _target to 1 after the while loop so the progress bar goes all the way

    • @muhammahnumanmughal7817
      @muhammahnumanmughal7817 Před rokem

      Hello. Your comment is fresh so you might have solved the problem I am facing.
      "Not a developer, just trying to make my game run." await Task.Delay is giving me error. It's saying "Task does not exists in the current context." please help

    • @feweks
      @feweks Před rokem

      @@muhammahnumanmughal7817 try removing async from the function name and getting rid of await Task.Delay

  • @kleioscope
    @kleioscope Před 5 měsíci

    too bad it just donw't work. At least it works when U3D loads a light scene that takes 0,1 microsec to load :(

  • @dormitando
    @dormitando Před měsícem

    Hey man are you by chance a web dev or have been in the past?

  • @indiyanathan3303
    @indiyanathan3303 Před 2 lety

    scenemanager not in visual studio

    • @Tarodev
      @Tarodev  Před 2 lety +3

      Add "using UnityEngine.SceneManagement" to the top of the file

  • @DigitalcommerceChannel
    @DigitalcommerceChannel Před 2 lety +1

    It didn't work for me: the loading bar just shows after the next scene has been loaded. In the meantime the first scene just freezed...unity sucks!

    • @ammarahmed3432
      @ammarahmed3432 Před rokem +1

      I have the same issue do you solve it

    • @DigitalcommerceChannel
      @DigitalcommerceChannel Před rokem

      @@ammarahmed3432 yes, i placer most of the code in yhe update function.

    • @onigiri_sakaro
      @onigiri_sakaro Před rokem

      @Gustavo Dario Dominguez @@ammarahmed3432 I've spent nearly 4 hours on this and it still won't work properly (total unity noob here btw). But i figured some things out, maybe this will help:
      - to make the Buttons work right, attach the "ChangeSceneButton" script file from the Project folder to the "Button" in the Hierarchy. Then drag the "Button" from the Hierarchy onto the Buttons OnClick Component in the Inspector. Then you get a list of functions. Choose > ChangeSceneButton > ChangeScene (string) and type "Scene 2" in the field below (and in the second Scene type "Scene 1" to go back.) My mistake was dragging the script from the Project Folder into the Inspector, which only gave 1 function called "string name" which didn't do anything).
      - make sure you add both scenes to the Build Settings (go to > File > Build Settings and then click add open scenes, or drag and drop them from the Project folder into the Build Settings window.)
      hope that helps!
      loader bar still won't work for me, but at least i can switch scenes now. unity. smh.

  • @sagrgywejhxcvx
    @sagrgywejhxcvx Před rokem

    no it does not work in big game

  • @B34Rocky
    @B34Rocky Před 2 lety +1

    Please guys help me, I use you tutorial completely and now i have a big problem with .meta files and nothin will work :(

    • @Tarodev
      @Tarodev  Před 2 lety +1

      What do you mean? Not sure what has happened.

  • @mohokhachai
    @mohokhachai Před 10 měsíci

    You are so close

  • @loosefootgoose919
    @loosefootgoose919 Před rokem +1

    Dont follow this tutorial without putting a fallback to get out of the do-while loop. I hit an infinate loop and lost an hours worth of work!

  • @Renegen1
    @Renegen1 Před 3 lety +11

    I think your videos show a high level of skill with programming, but you're a lousy teacher. You simply can't do 5 other things not related to the task you're teaching. Every time you create any kind of special variable, function, you need to reference that to other videos which describe in depth that task separately. This is how you can choose your next videos. Every single logic in your code needs its own unique video, and it needs to be explicitly acknowledged.
    Also, tying all your videos into a single large project helps immensely. Too many videos start already with a setup situation that the viewer may not relate to.

    • @Tarodev
      @Tarodev  Před 3 lety +26

      Valid points and something I'm slowly starting to improve (I've been told once or twice I need to explain certain lines a bit clearer). A major component of not doing it is because I'm trying to make my videos short and to the point... Explaining every line would make each video 30 minutes long, which is the opposite of what I wanted for the channel. For example I don't fill my videos begging for subs or shove any unessersary life story in your face as I don't want to waste your time.
      I'll keep this in mind as it's good advice. From now on if I write a special line I'll either link to another video of mine or somebody else's.
      Thanks for taking the time to give valuable feedback 👍

  • @arcanep
    @arcanep Před 2 lety +7

    cause some fellow gamedevs are def lazy like I am
    //I used a slider not an image for mine but it should work just as well with an image
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    using System.Threading.Tasks;
    public class LevelManager : MonoBehaviour
    {
    public static LevelManager instance;
    [SerializeField] private GameObject _loaderCanvas;
    [SerializeField] private Slider _progressSlider;
    private float _target;
    private void Awake()
    {
    if(instance == null)
    {
    instance = this;
    DontDestroyOnLoad(gameObject);
    }
    else
    {
    Destroy(gameObject);
    }
    }
    public async void LoadScene(string sceneName)
    {
    _target = 0;
    var scene = SceneManager.LoadSceneAsync(sceneName);
    scene.allowSceneActivation = false;
    _loaderCanvas.SetActive(true);
    do
    {
    await Task.Delay(1000); //artifical wait time
    _progressSlider.value = scene.progress;
    }
    while(scene.progress < 0.9f);
    //await Task.Delay(1000);
    scene.allowSceneActivation = true;
    _loaderCanvas.SetActive(false);
    }
    private void Update()
    {
    _progressSlider.value = Mathf.MoveTowards(_progressSlider.value, _target, 3 * Time.deltaTime);
    }
    }