- Home /
The question is answered, right answer was accepted
Load a random scene from a list of strings.
I am wanting to load a random scene from a list of strings/names instead of using the build menu index, for example, here is some sort of Pseudo code version of what I am wanting to do.
//Declared as variables so that I can specify only the levels I want to load.
LevelOption1 = "LevelTrain";
LevelOption2 = "LevelBoat";
LevelOption3 = "LevelCar";
LevelOption4 = "LevelBike";
SceneToLoad = [Range.Random (LevelOption1, LevelOption2, LevelOption3, LevelOption4)];
Use SceneManager.LoadScene (SceneToLoad);
I know this is very rough and incredibly broken but I am new to coding. I do not want to have to use something like Random.Range(1, 10) because all levels are not in sequence in the build settings. Any help is appreciated. If this can't be done, any solutions would be helpful.
Answer by RonanSmithDev · Oct 26, 2016 at 10:30 PM
After trying to use the scripts you provided I decided on a less elegant but much easier to understand script of my own; using the random number range I create an integer between 0 and 8 because I have 7 levels to randomize, I then use IF statement to read from this integer and if it matches the number on the IF statement it triggers the level to load. I wrote all of the script out in C# only to find that static string variables cannot (to my knowledge) be made public and edited in the inspector using C# so I re wrote it in JS. I know that this is not an optimal solution but it is one that seems to work, unless you see any massive problems with this method?
#pragma strict
private var RandNum : int;
var LvlZero : String;
var LvlOne : String;
var LvlTwo : String;
var LvlThree : String;
var LvlFour : String;
var LvlFive : String;
var LvlSix : String;
var LvlSeven : String;
//Remove or add variable and corresponding IF statement to scale
function Start ()
{
//Second property must be 1 over desired range
RandNum = Random.Range(0, 8);
print(RandNum);
if (RandNum == 0)
{
Debug.Log("Scene0");
SceneManagement.SceneManager.LoadScene(LvlZero);
}
if (RandNum == 1)
{
Debug.Log("Scene1");
SceneManagement.SceneManager.LoadScene(LvlOne);
}
if (RandNum == 2)
{
Debug.Log("Scene2");
SceneManagement.SceneManager.LoadScene(LvlTwo);
}
if (RandNum == 3)
{
Debug.Log("Scene3");
SceneManagement.SceneManager.LoadScene(LvlThree);
}
if (RandNum == 4)
{
Debug.Log("Scene4");
SceneManagement.SceneManager.LoadScene(LvlFour);
}
if (RandNum == 5)
{
Debug.Log("Scene5");
SceneManagement.SceneManager.LoadScene(LvlFive);
}
if (RandNum == 6)
{
Debug.Log("Scene6");
SceneManagement.SceneManager.LoadScene(LvlSix);
}
if (RandNum == 7)
{
Debug.Log("Scene7");
SceneManagement.SceneManager.LoadScene(LvlSeven);
}
}
Thankyou @N1warhead and @MoonHeadJohn for your input, it is greatly appreciated!
Answer by N1warhead · Oct 20, 2016 at 03:29 PM
This should work. Keep in mind it isn't tested. it still uses a random range. But in a different way than what you are doing. This way it's exactly the proper level order you want, not based on BuildSettings.
This is C# also.
// This isn't tested. But should work. You'll still have to use Random.Range, but you'll see what I mean.
// be sure to include "using System.Collections.Generic;" at the top Without "".
// Not tested, but no compile errors on my end.
private int indexId; // We use this as a way to access our list of strings.
private string levelToLoadName = ""; // We leave it blank first.
public List<string> levelNames = new List<string>(); // It's public so you can put level names inside inspector. Cleaner that way. (to me at least).
// Only using start as an example.
void Start(){
/*
* Alright, it's fairly simple.
* All you have to do, is do a random.range for the index inside the list, like so.
*/
// If you run into any problems with this. Try putting either -1 or levelNames.Count - 1;
indexId = Random.Range (0, levelNames.Count); // Obviously 0 is minimum, and we get the max amount of strings inside the list. And choose a random level in it.
// We now set the levelToLoadName to the name of the string at the index inside the List.
levelToLoadName = levelNames[indexId];
SceneManager.LoadScene (levelToLoadName); // Now we load the level.
}
Been attempting to implement this in a test project, I am new to coding so have little idea what I am doing, I keep getting the error “A namespace cannot directly contain members such as fields or methods” I have looked this up but could find no fix. Any idea what I am doing wrong or is there another solution? Thanks.
It sounds like you haven't copied this into the scope of a class. Here's what it should look like if I copy N1warhead's answer:
using UnityEngine;
public class RandomLevel : $$anonymous$$onoBehaviour
{
private int indexId;
private string levelToLoadName = "";
public List<string> levelNames = new List<string>();
void Start() {
levelNames.Count - 1;
indexId = Random.Range (0, levelNames.Count);
levelToLoadName = levelNames[indexId];
Scene$$anonymous$$anager.LoadScene (levelToLoadName);
}
}
Edit: Apologies for the formatting, I need to get used to it.
Apologies, Still no luck, even included the "using system.collec.." line at the top too. I also tried adding "using UnityEngine.Scene$$anonymous$$anagement;" because Ive seen that needs to be there if you are using Scene $$anonymous$$anager to load with. Am I doing something really simple wrong?
EDIT: Could a possible workaround be to use IF statements?
For example, create a random number generator to generate a number (n) between 1 and however many scenes, after that use IF statements to say: IF n = 3, load a certain level.
using UnityEngine;
using UnityEngine.Scene$$anonymous$$anagement;
using System.Collections.Generic;
// Change NameOfYoruScriptFile to the name of the file (This is your class name)....
// This is the same as my answer above, only edited to have the formatting for the
// Class and such, and removed comments to remove the clutter.
// Read the comments in my above answer if you have any problems.
// ALSO: What errors are you getting in the first place?
public class NameOfYourScriptFile : $$anonymous$$onoBehaviour {
private int indexId;
private string levelToLoadName = "";
public List<string> levelNames = new List<string>();
void Start(){
indexId = Random.Range (0, levelNames.Count);
levelToLoadName = levelNames[indexId];
Scene$$anonymous$$anager.LoadScene (levelToLoadName);
}
}
Follow this Question
Related Questions
help please: Level Changing Scipt 1 Answer
Single scene, multiple levels 1 Answer
Loading last scene 1 Answer
How to use DontDestroyOnLoad only once 1 Answer
Level advancment Scirpt 1 Answer