0
\$\begingroup\$

I am making a strategy game where the player roams a grid map. When the player encounter enemy on the map he is transferred to a "battle" scene where two armies are fighting in turn based battle. Imagine Heroes 3 like game.

My question is:

  1. Should I load the battle scene in additive mode and temporary hide the "world map" and when the battle is finished to just show the "world map" and hide the "battle" scene?

  2. Or i should unload the world scene and load the battle scene, and when the battle is over -> unload the battle scene and load the world scene ?

I think the 1st approach will give me less loading time between the two scenes, but will require more RAM ?

Second approach is standard one, but i will have loading between the scenes ?

My idea is to have no or minimal loading between battle and world scenes.

What do you guys thing ? Did you know what is the best practice in this case ?

By the way, i am using Unity as a engine.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ You seem to have laid out the pros and con of every approach very well. All that is left is to decide. its a subjective decision. \$\endgroup\$
    – Polygnome
    Commented Jul 10, 2020 at 11:06
  • 1
    \$\begingroup\$ As Polygnome says, you should trust your understanding of the problem. It's a space-time trade-off, so you just need to figure out whether the space or the time is more precious in your case, and you can do that by profiling. Build a sample with a representative amount of content for each view (it doesn't have to be real final content, just enough placeholder objects/polygons/scripts to simulate a similar load). Test the scene load on your target hardware: is it too slow for your needs? Test the RAM utilization of having both present: is it too heavy for your needs? You got this! \$\endgroup\$
    – DMGregory
    Commented Jul 10, 2020 at 11:56

2 Answers 2

1
\$\begingroup\$

For minimum loading times, you can have both the world map and the battleground in the same scene as two different gameObjects.

One option would be to have both of them in the same space as two different gameObjects and just deactivate the one you are not currently playing on. You can also keep both active and use rendering layers to tell the camera which one to render at any given moment. This option would be required when you want to use baked global illumination, so the two objects won't cast lights or shadows on each other. Also keep in mind that you need to avoid any physics collisions between the two different objects.

If you want to use physics-based rendering with pre-baked lightmaps but don't want to use rendering layers and don't want to worry about physics collisions either, then another options would be to use spacial separation. Like placing the battleground at Y-coordinate +1000 and the world map at Y-coordinate -1000. Just make sure that the camera far-plane distance is short enough that the player isn't going to see the other when looking up or down.

\$\endgroup\$
0
\$\begingroup\$

This is possible now without additive scenes by using async.allowSceneActivation.

Note: Unity will CRASH if you don't let it complete any async load operation that you start. so...

  • Don't exit play mode while an async load is waiting to be activated.
  • Don't let players cancel scene transitions once the async load starts

Less important notes:

  • Your next scene's initialization is probably the real problem, try to optimize init before worrying about async load.

  • The lag that appears when you first call LoadLevelAsync is only present in the editor.

public string levelName;

     AsyncOperation async;
 
     public void StartLoading() {
         StartCoroutine("load");
     }
     
     IEnumerator load() {
         Debug.LogWarning("ASYNC LOAD STARTED - " +
            "DO NOT EXIT PLAY MODE UNTIL SCENE LOADS... UNITY WILL CRASH");
         async = Application.LoadLevelAsync(levelName);
         async.allowSceneActivation = false;
         yield return async;
     }
 
     public void ActivateScene() {
         async.allowSceneActivation = true;
     }

Just call StartLoading() when you are certain that a scene transition is incoming and then ActivateScene() when you are ready to swap. I'm willing to live with the danger of unity crashes to avoid the hassle of additive scene loading.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .