Multiple levels best practise
What is the intended/best setup for a game with multiple levels? I can't find much of a clear message on this but it 's pretty major part of game architecture/workflow.
My specific case is a very simple 2D game in which I want to have many levels. These levels will use mostly the same assets, but with different placement. From what I've read so far it seems the options are:
1) Separate scene for each level. This will involve some loading/unloading, which means load times. How significant are these likely to be?
2) All levels in one scene (or maybe say 5 levels per scene). This means having more stuff loaded at once, using more memory. Is that problematic?
3) One scene, but each level is loaded when needed. Intuitively this seems like the best option, but I have no idea how to implement it. I've seen suggestions of making levels in the editor, saving them, then loading them when needed but haven't found any reference for how to do this. What is the workflow here? Also, is this method better than #1 which also involves loading data for every level?? I'm thinking it would be if your prefabs are all already loaded.
Any help would be much appreciated, thanks!
Answer by Statement · Oct 27, 2015 at 08:25 PM
Here's a mix of my experiences and my expectations.
Workflow relatively easy if you are working in a team. Each member can freely edit their scene without worrying about anyone else messing with the same scene. It's possible you get some loading times, yes, but it's highly dependable on what kind of content can be reused and what level you are loading. Each level will be unique in their load times. Not so much of an issue for small levels.
Horrible workflow for a team. Conflicts happen several times a day and merging is not easy. Runtime performance can suffer in some cases where scripts from other levels are executing. Make sure to turn everything off if you can. Longer initial loading times for that set of levels, but generally a lot faster to switch between the levels. Be careful of subtle bugs where for example you might have messed up a state of a level. Consider playing level 1, playing level 2, then returning to level 1. Level 1 is in a state of where you left it. Special care has to be taken to make sure your game works for retries. Yes, memory usage can be a problem but only if you are using a lot of assets. It's hard to gauge if you are a hobby dev or if you got a backing of multiple artists and designers ready to poise a full on experience.
Note that you can also work with your own scenes and then as a build step compile several scenes together with LoadLevelAdditive and saving the result to a new scene. This won't be that unforgiving on team members, but make sure your game doesn't break or run out of memory :)Not so much experience with it. You'd use Application.LoadLevelAdditive. It can get confusing to develop like this because you won't have a reference point to where the other objects are in other levels when you develop it. Also if your levels require stuff from the "main scene", you have to load that back in Unity before you hit play, so it'll be a lot of going back and forth for testing stuff out. But yes, it's possible and some people use it. Though I am not sure what your benefit will be. You can also export selected objects into a scene you later can load additive. You can export through editor extensions you find, buy or write yourself.
Perhaps you could start off with #1 as it's most intuitive to work with imo. If it becomes a real problem to deal with loading times, you could try to adapt it into #2 or #3 if you can't figure out a way to reduce loading times. For example I've experienced lots of shaders on mobile devices eat up fair share of time. So we addressed shaders (simplifying, stripping out unneeded passes or variants) and more than halved our loading times.
It's also highly dependable on what is going to be different for every scene. For example if you load in a tilemap, perhaps it's easier to just define the level in a tile editor and then have a script in Unity that instantiates stuff from that file. There isn't a one true answer to fit all problems I think. Figure out what you need, what your worries are and then see if they are real problems and what you can do about them. Don't be afraid of trying something new.
Thanks for your input, I appreciate it. I think I will start with #1 and see where that takes me. Honestly there's not much going on in my game so I suspect it will be fine. $$anonymous$$ainly just interested on best practise and the rationale behind working in different ways.
I think what you described at the end of your post is more what I meant by #3 - i.e. using a script to instantiate prefabs based on some kind of file storing the level layout.
(Also, I'm a hobbyist.)
I fully understand the wish to conform to "this is the way to do it" style of thinking. Unity (or any software) is a complicated machinery with lots of moving parts. Usage of it is not linear. People do all kinds of crazy things, with different approaches and outcomes. $$anonymous$$y advice to you is to try and stick to something simple until you notice issues with it. Another issue is that you may overthink things or overengieneer solutions that aren't really required. You could spend time making an extensive framework you won't end up using. Then what use was it other than a program$$anonymous$$g exercise? It's very difficult to find a balance and know when to prepare a system in advance.
When you are learning, it could be beneficial if you are reactive and reflect on your problems rather than conjuring them up from thin air. Let's say your level loading is your concern. When is it too slow? Is 1 second too slow? Is 5 seconds too slow? Set up a benchmark if you really think it is very important for your game. Then write a script that tells you in console when you're spending too long in Load, or remotes to an arduino robot that pour cold water down your neck. Anything to get your attention. Then you know "shit, I am dipping into crapland where customers will get annoyed. What can I do? What was my latest change? Can I figure out why it is slow and what I can do about it?". Or if you really are concerned in pinpointing what changes spike your load time you could put in load analytics. $$anonymous$$eep it simple. Every time you load a level, print to a file from which level you came, to which level you went, and how long it took. Then you can review that log later and perhaps see that on Jun 6 2016, loading time doubled. What did I do Jun 6? This is likely my biggest problem. Etc.
Anyway, you'll learn from what works and doesnt work, for certain scenarios. And there are lots of scenarios. keep a note of things that concern or bug you and see if you ever get a problem with them. $$anonymous$$eep a list of things that were difficult so you can avoid/learn/improve on them in the future.