- Home /
Architecture: How to load a level from a user-selected file?
I have a game which provides a level editor to the user in which he can place some simple walls and collectibles. These are stored in a folder on hard disk, one file for one level.
Then I have a UI-powered scene providing a list of these files, and the user selects one to load it up in a new scene. But I'm not sure how I'd do that.
I had a look at the answer here: http://answers.unity3d.com/answers/578928/view.html But in the example code, the name of the level file is hardcoded ("D:\level1.txt"). Of course the first logical step would be to make that file name a public member of the class to set it from the outside.
This doesn't help me though. To set the file name, I'd need to have this script on an empty game object in an empty scene. I can't create a scene for each level, as the level list is dynamic.
So I'd have to create the scene, with the empty game object and script with the correct level file name at runtime. How would I do that? Or is there a better solution?
Answer by Immanuel-Scholz · Apr 15, 2016 at 10:51 AM
I assume that you are developing for Windows Standalone or Mac or Linux. If you target mobile platforms or WebGL, accessing the users file system is not possible. You would find another solution to store the files there than to dump them into an arbitrary directory..
Anyway, System.IO.Directory.GetFiles
is your friend here. It lists the context of a directory on the file system.
using System;
using System.IO;
...
string documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string[] filePaths = Directory.GetFiles(documents + "/MyAwesomeLevels/", "*.xml");
// now, 'filePaths' hold paths to all *.xml files located under C:/User/<login>/Documents/MyAwesomeLevels/
Edit: Apparently, the question was not about how to retrieve the file name, but about how to "load a new scene from that file name".
To create a new Scene, call SceneManager.CreateScene("Name of the scene")
. Then set it as active scene, so all newly created objects are placed into that scene. Finally, create your objects ("new GameObject" etc...). To unload this scene later, use SceneManager.UnloadScene
using UnityEngine.SceneManagement;
...
// Create a new empty scene with the name
var newScene = SceneManager.CreateScene("someLevel");
// make it active
SceneManager.SetActiveScene(newScene);
// fill with data
for (...)
{
var go = new GameObject(...)
go.AddComponent<...>();
...
}
// later, when you don't need the scene anymore:
SceneManager.UnloadScene("someLevel");
Thanks for the WebGL clarification. I keep that in $$anonymous$$d, though I didn't plan to develop for WebGL anyway. However, I know already how to iterate my files and create a list out of them. $$anonymous$$y question was how I'd pass the specific, selected level file to the "in-game" scene, which then loads the data from the one file the user selected.
Ok, clarified the answer.
One more note: If you run 5.4 beta, Be sure to update to the very latest beta. There was a crash bug when unloading additive scenes up until 5.4.0b14
Thanks! This is a really great answer. I had no clue it was possible to create scenes from script (in fact I read several (outdated) answers which always said "don't do it", "not possible"), so I was a bit confused.