Manuel Mangual
Manuel Mangual

Reputation: 75

Issues loading different levels randomly in Unity-3D

I need to create a class (or classes, if need be) that loads levels randomly every time the user clicks on the "Next Button" and once all levels have been loaded, we stop loading and close the application. I got the code set up but I am still not getting the result I am looking for which is:

  1. User clicks on a button.

  2. Load a random level

  3. That levels gets stored in an array list

  4. Once the user is done with that level he/she presses the "Load Next Level" button

  5. Load the next random level

  6. But first, we check if the random level is not the same as before.

  7. If it's not, then we repeat steps 2-5, else we go to step 8

  8. If the levels have all been visited then we quit the application

The problem I am having is that my game loads the same level every time I hit play and it doesn't go to the next scene after I am done with the current one. This is what I have so far:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class SceneManager : MonoBehaviour
{
    public static bool userClickedNextButton;   //This flag is raised by the other classes that have the GUI button logic

    protected const int MAX = 2;

    private ArrayList scenesWereAlreadyLoaded = new ArrayList();

    void Update()
    {
        if (userClickedNextButton)
        {
                //by default the game starts at 0 so I want to be able to 
                //randomly call the next two scenes in my game. There will
                //be more levels but for now I am just testing two
                int sceneToLoad = Random.Range(1, 2);
                if (!scenesWereAlreadyLoaded.Contains(sceneToLoad))
                {
                    scenesWereAlreadyLoaded.Add(sceneToLoad);
                    Application.LoadLevel(sceneToLoad);
                }
                userClickedNextButton = false;

        }
        if (scenesWereAlreadyLoaded.Count > MAX) { Application.Quit(); }
    }
}

Upvotes: 0

Views: 2508

Answers (3)

Letaief Achraf
Letaief Achraf

Reputation: 650

There is an easier way to do so. You can prepare an array with random unique numbers. When you want to load a new level just increment the index of the array. Here's a code that can help:(Attach this script to an empty gameobject in your first scene)

  using UnityEngine;
  using System.Collections;


  public class MoveToRandomScene : MonoBehaviour {
  public Texture nextButtonTexture; // set this in the inspector 
  public static int[] arrScenes;
  public static int index;
  void Start () {
    index = 0;
    arrScenes = GenerateUniqueRandom (10, 0, 10); //assuming you have 10 levels starting from 0.

}

void OnGUI {
// Load the first element of the array
    if (GUI.Button(new Rect (0,0,Screen.width/4,Screen.height/4),nextButtonTexture))
    {
    int level = arrScenes [0] ;
    Application.LoadLevel (level);
    }
}
//Generate unique numbers (levels) in an array
public int[] GenerateUniqueRandom(int amount, int min, int max)
{
    int[] arr = new int[amount];
    for (int i = 0; i < amount; i++)
    {
        bool done = false;
        while (!done)
        {
            int num = Random.Range(min, max);
            int j = 0;
            for (j = 0; j < i; j++)
            {
                if (num == arr[j])
                {
                    break;    
                }
            }
            if (j == i)
            {
                arr[i] = num;
                done = true;
            }
        }
    }
    return arr;
}

}

For the other scenes you just need to create this script and attach it to an empty game object whenever you want to load a new random scene:

void OnGUI {
    if (GUI.Button(new Rect (0,0,Screen.width/4,Screen.height/4),nextButtonTexture))
    {
       if (MoveToRandomScene.index == 9) {
       // Load again your first level
       Application.LoadLevel(0);
    }
    // else you continue loading random levels
    else {
    MoveToRandomScene.index++;
    int level = MoveToRandomScene.arrScenes[MoveToRandomScene.index];
    Application.LoadLevel(level);
    }
 }
}

Upvotes: 1

Tseng
Tseng

Reputation: 64180

You create a list with your level numbers, then remove the currently loaded level. You repeat that until the list is empty.

Also don't use ArrayList, it's very old and deprecated type, from the ages before .NET/Mono had Generic support. Better use a Generic List<T>, which is type safe and faster than ArrayList.

using UnityEngine;
using System.Collections;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

[ExecuteInEditMode]
public class SceneManager : MonoBehaviour
{
    // not best idea to have it static 
    public static bool userClickedNextButton;

    protected const int MAX = 50;

    private List<int> scenes = new List<int>();
    void Start() {
        // Initialize the list with levels
        scenes = new List<int>(Enumerable.Range(1,MAX)); // This creates a list with values from 1 to 50
    }
    void Update()
    {
        if (userClickedNextButton)
        {
            if(scenes.Count == 0) {
                // No scenes left, quit
                Application.Quit();
            }

            // Get a random index from the list of remaining level 
            int randomIndex = Random.Range(0, scenes.Count);
            int level = scenes[randomIndex];
            scenes.RemoveAt(randomIndex); // Removes the level from the list
            Application.LoadLevel(level);

            userClickedNextButton = false;
        }
    }
}

Upvotes: 2

Ricardo Rodriguez
Ricardo Rodriguez

Reputation: 1090

As per the Unity3D documentation (http://docs.unity3d.com/Documentation/ScriptReference/Random.Range.html), range returns an integer between min (included) and max (excluded), so, in your case, Random.Range(1,2) will always returns 1.

Try with this

int = sceneToLoad = Random.Range(1,3)

Upvotes: 2

Related Questions