Announcement

Collapse
No announcement yet.

How to open level asynchronously, without visible after load?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to open level asynchronously, without visible after load?

    I have tryed Streaming Levels, but this is not what i need. Because if i make level - Steamable and then use UGameplayStatics::LoadStreamLevel, then level is loaded, but GameMode, PlayerController and HUD is not changed. I need it to be changed, like when normal load map.

    I need something like UGameplayStatics::OpenLevel, but with async load, and with bMakeVisibleAfterLoad = false.

    Any suggestions?

    For example:
    I have MainMenu, CharacterCreationMenu and GameWorld.
    When i start game i am inside MainMenu, then i press login, and i go into CharacterCreationMenu, when i finished creating character i am going into GameWorld. (Typical game design).
    But, i dont want game FREEZ, when i switch between this levels, i dont want LOADING.
    So i want, when game starts, i am go into MainMenu, but, in the same time CharacterCreationMenu and GameWorld continue loading into memory asynchronously, while i am inside MainMenu.

    Dummy solution:
    I can try to do the following, i can use single GameMode, single PlayerController and HUD, for all MainMenu, CharacterCreationMenu and GameWorld, and make internally/manually switching functionality inside that classes, when i load another level. So, i could use level streaming, and manual HUD switching for example. I.e. i could make all 3 HUDS inside 1 HUD. Is it right solution? or there is async OpenLevel, like i need?

    IMPROTANT NOTE: GameWorld probably is going to be WorldComposition, so i dont know yet, is it possible to use WorldComposition level like streaming level of another level. EDIT: no, WorldComposition cannot be streaming level: https://answers.unrealengine.com/que...#answer-256545
    So, i have to OpenLevel(GameWorld) somehow, asynchronously.

    thx.

    EDIT1:
    The closest solution i found for now, is World->SeamlessTravel(), which is loading map synchronously, but at least with loading screen. Ofc this is not what i need, but for now this is all i found.

    EDIT2:
    I've tested a little SteamlessTravel, and i wanna say, that it is very bugged and very strange. First of all, SeamlessTravel can load streaming levels, regardless it's PersistentLevel, with loading new GameMode and without unloading PersistentLevel GameMode (which is automatically becoming Garbage collected only after couple of minutes)... Second, is that all actors in editor's World Outliner become deleted, wtf?. Third, as i understand, SeamlessTravel is somehow related with UE4 server handling, which i dont need, i need only client.

    EDIT3:
    SteamlessTravel bug - when i load WorldComposition with SeamlessTravel, then sublevels are not loaded and if i try to load them with LoadSteamLevel - it fails.

    EDIT4:
    FSeamlessTravelHandler contains similar functionality what i need, it has example of asynchronous map loading, using LoadPackageAsync. And also example of how to change CurrentWorld to LoadedWorld. But as i said it EDIT3, it is working with some bugs.

    EDIT5:
    I think i can do smth that may help to my problem, i can load map package asyncronously (for example by using FStreamingManager or LoadPackageAsync) and keep pointer to that package to prevent garbage collecting, and then i can call OpenLevel when needed, potentially this can increase loading speed, because OpenLevel automatically determine if needed package is already loaded. This will not work so simple, because each map also contains many other asset references which also need to be loaded asyncly, so loading just single map package will give not much (UEngine::LoadPackagesFully, which is synchronous).

    EDIT6:
    Some useful links about map changing:
    https://answers.unrealengine.com/que...ml?sort=oldest
    https://answers.unrealengine.com/que...s-network.html
    I've tested PrepareMapChange and CommitMapChange, its kind of old version of level streaming, bugged and outdated i suppose.

    CONCLUSION:
    There is no such functionality as i want in UE4.8 yet, i.e. async non-streamable map loading/precaching for later activation (LoadLevelAsync).
    - SeamlessTravel (ServerTravel/ClientTravel) - working with bugs in PIE mode.
    - PrepareMapChange and CommitMapChange - working with bugs in PIE mode.
    - FStreamingManager - not supposed to be used in PIE mode, as i understand, thats strange, so its also bugged in PIE mode.

    CURRENT SOLUTION:
    Use LoadPackageAsync function for precaching map and then manually prevent it from garbage collecting (AddToRoot maybe), and then use regular UGameplayStatics::OpenLevel when needed, it will automatically find precached map with specified name. Or just use UGameplayStatics::OpenLevel for now, without any async precache...
    Last edited by newbprofi; 07-12-2015, 05:47 PM.

    #2
    Originally posted by newbprofi View Post
    I have tryed Streaming Levels, but this is not what i need. Because if i make level - Steamable and then use UGameplayStatics::LoadStreamLevel, then level is loaded, but GameMode, PlayerController and HUD is not changed. I need it to be changed, like when normal load map.

    I need something like UGameplayStatics::OpenLevel, but with async load, and with bMakeVisibleAfterLoad = false.

    Any suggestions?

    For example:
    I have MainMenu, CharacterCreationMenu and GameWorld.
    When i start game i am inside MainMenu, then i press login, and i go into CharacterCreationMenu, when i finished creating character i am going into GameWorld. (Typical game design).
    But, i dont want game FREEZ, when i switch between this levels, i dont want LOADING.
    So i want, when game starts, i am go into MainMenu, but, in the same time CharacterCreationMenu and GameWorld continue loading into memory asynchronously, while i am inside MainMenu.

    Dummy solution:
    I can try to do the following, i can use single GameMode, single PlayerController and HUD, for all MainMenu, CharacterCreationMenu and GameWorld, and make internally/manually switching functionality inside that classes, when i load another level. So, i could use level streaming, and manual HUD switching for example. I.e. i could make all 3 HUDS inside 1 HUD. Is it right solution? or there is async OpenLevel, like i need?

    IMPROTANT NOTE: GameWorld probably is going to be WorldComposition, so i dont know yet, is it possible to use WorldComposition level like streaming level of another level. EDIT: no, WorldComposition cannot be streaming level: https://answers.unrealengine.com/que...#answer-256545
    So, i have to OpenLevel(GameWorld) somehow, asynchronously.

    thx.

    EDIT1:
    The closest solution i found for now, is World->SeamlessTravel(), which is loading map synchronously, but at least with loading screen. Ofc this is not what i need, but for now this is all i found.

    EDIT2:
    I've tested a little SteamlessTravel, and i wanna say, that it is very bugged and very strange. First of all, SeamlessTravel can load streaming levels, regardless it's PersistentLevel, with loading new GameMode and without unloading PersistentLevel GameMode (which is automatically becoming Garbage collected only after couple of minutes)... Second, is that all actors in editor's World Outliner become deleted, wtf?. Third, as i understand, SeamlessTravel is somehow related with UE4 server handling, which i dont need, i need only client.

    EDIT3:
    SteamlessTravel bug - when i load WorldComposition with SeamlessTravel, then sublevels are not loaded and if i try to load them with LoadSteamLevel - it fails.

    EDIT4:
    FSeamlessTravelHandler contains similar functionality what i need, it has example of asynchronous map loading, using LoadPackageAsync. And also example of how to change CurrentWorld to LoadedWorld. But as i said it EDIT3, it is working with some bugs.

    EDIT5:
    I think i can do smth that may help to my problem, i can load map package asyncronously (for example by using FStreamingManager or LoadPackageAsync) and keep pointer to that package to prevent garbage collecting, and then i can call OpenLevel when needed, potentially this can increase loading speed, because OpenLevel automatically determine if needed package is already loaded. This will not work so simple, because each map also contains many other asset references which also need to be loaded asyncly, so loading just single map package will give not much (UEngine::LoadPackagesFully, which is synchronous).

    EDIT6:
    Some useful links about map changing:
    https://answers.unrealengine.com/que...ml?sort=oldest
    https://answers.unrealengine.com/que...s-network.html
    I've tested PrepareMapChange and CommitMapChange, its kind of old version of level streaming, bugged and outdated i suppose.

    CONCLUSION:
    There is no such functionality as i want in UE4.8 yet, i.e. async non-streamable map loading/precaching for later activation (LoadLevelAsync).
    - SeamlessTravel (ServerTravel/ClientTravel) - working with bugs in PIE mode.
    - PrepareMapChange and CommitMapChange - working with bugs in PIE mode.
    - FStreamingManager - not supposed to be used in PIE mode, as i understand, thats strange, so its also bugged in PIE mode.

    CURRENT SOLUTION:
    Use LoadPackageAsync function for precaching map and then manually prevent it from garbage collecting (AddToRoot maybe), and then use regular UGameplayStatics::OpenLevel when needed, it will automatically find precached map with specified name. Or just use UGameplayStatics::OpenLevel for now, without any async precache...
    I'm so glad you made this post. I literally was about to create one asking the same thing.

    Considering the limitations of using World Composition, I need the exact same thing and it could limit the features of my game if I can't get around it. I want to pre-load a level into memory and switch it when I am ready while hoping to also be notified by a callback that the level finished loading and is ready. Then a node to switch levels instantly with no jutter and no "black" or "frozen" frames in between while having the option to call a node to gracefully remove the last level from memory w/out any stuttering.

    Also, I have to take a look at this to see if it's already possible but I have a specific use case where I need to load the level specifically on the client where players could be in different levels at the same time but on the same server.

    Hopefully the devs over at Epic can share a couple thoughts when they get back into the office tomorrow.

    I'll be keeping my eyes on this thread and stay hopeful!
    Last edited by MC Stryker; 07-12-2015, 09:09 PM.

    Comment


      #3
      Adding a friendly bump to this post just in case it got missed

      Comment


        #4
        Originally posted by newbprofi View Post
        Use LoadPackageAsync function for precaching map and then manually prevent it from garbage collecting (AddToRoot maybe), and then use regular
        Yeah, this is right way. You will need some kind of UMapPreloader that could load map package in background and keep reference to it. Then when it's finished you could initiate seamless travel.
        Seamless travel code will need some changes, it should first try to find destination package in memory and initiate loading only when it fails.
        When your manager works in c++ then could always expose it's functionality to BP.

        Comment


          #5
          Originally posted by ddvlost View Post
          Yeah, this is right way. You will need some kind of UMapPreloader that could load map package in background and keep reference to it. Then when it's finished you could initiate seamless travel.
          Seamless travel code will need some changes, it should first try to find destination package in memory and initiate loading only when it fails.
          When your manager works in c++ then could always expose it's functionality to BP.
          Hey ddvlost,

          Just wanted to ask what you thought about the use case I described above and if something like this would be possible? Hope you and the team are doing well. Thanks!

          Comment


            #6
            Does this still apply in 4.10 or is there a better / more straight-forward way of opening a level async now?

            Thanks

            Comment


              #7
              Is there any updates to this? I need the very same implementation.

              AddToRoot is crashing on android. Rama suggested here https://answers.unrealengine.com/que...-root-set.html to add as a UPROPERTY Instead. But everything looks a bit shady.

              I wish we had LoadLevelAsync like unity

              Comment


                #8
                Originally posted by newbprofi View Post
                CURRENT SOLUTION:
                Use LoadPackageAsync function for precaching map and then manually prevent it from garbage collecting (AddToRoot maybe), and then use regular UGameplayStatics::OpenLevel when needed, it will automatically find precached map with specified name. Or just use UGameplayStatics::OpenLevel for now, without any async precache...
                When I do that OpenLevel crashes with "assertion failed: NewWorld". Im on 4.17

                Comment


                  #9
                  necro

                  Please enter a message with at least 10 characters

                  Comment


                    #10
                    solved. Please enter a message with at least 10 characters

                    Comment

                    Working...
                    X