top of page

Level Generation Using Text Files



Before reading this blog, just take a look at the video above.

The question we are gonna answer in this blog is, "How do they generate levels in level-based games?" . Lets suppose a game has 300+ levels in it, Do you think they create 300 scenes in the game and load each scene? This doesn't look right, does it? ok , let me explain that. Lets suppose your game has 100 levels. Each level has 10 tiles in it. If you create 100 scenes with each scene having 10 tiles, you ultimately end up creating 100*10 = 1000 tiles(game objects) which is both waste of memory and time.

So what is the alternative?

Create a text file for each level. That text file contains positions and rotations of each gameobject in the scene/level. Lets suppose you have 100 levels, you create 100 text files. Now load the scene by reading that text file you have generated and generate your level dynamically from that text file. Here in this case, you end up creating 100 text files and one scene and depending up on the level you want to play, you load that text file on to the scene.

This method can save lot of memory because here you are just loading scenes when necessary from the text files instead of creating them initially in the game.

Sounds cool right?

In my previous blog, i have create an editor script which generates buttons, with each button having specific functionality.

Lets see how are we gonna store this position of the object on to a text file. Lets supose you create a button "CREATE TILE - STRAIGHT" in onGUI(). When ever you click this button a straight tile is created and its corresponding position and rotations are stored in text file.


 if (GUILayout.Button("CREATE TILE- STRAIGHT"))
                {
                    xPos += 2.1f;
                    GameObject _temp_tile = Instantiate(Resources.Load<GameObject>("Path"), new Vector3(xPos, yPos, zPos), Quaternion.Euler(new Vector3(-90, 0, 0)));
                    arrow.transform.position = new Vector3(xPos, 2.44f, zPos);

                    //adding to level Text file
                    LevelGeneratorData levelGeneratorData = new LevelGeneratorData();
                    levelGeneratorData.name = _temp_tile.name.Substring(0,4);
                    levelGeneratorData.position = _temp_tile.transform.position;
                    levelGeneratorData.rotation = _temp_tile.transform.rotation.eulerAngles;
                    savingData(levelGeneratorData.name, levelGeneratorData.position, levelGeneratorData.rotation);

                }

You see the last line of the code- SavingData() function which actually creates a text files and saved this tiles location and position on to the text file.



 public void savingData(string name, Vector3 location, Vector3 rotation)
    {
        //Function to save all objects locations
        string path = Application.dataPath + levelName;

        if (!File.Exists(path))
            File.WriteAllText(path, "Level1 \n");


        //content of File
        string content = name + ":" + location.x + "," + location.y + "," + location.z + "," + rotation.x + "," + rotation.y + "," + rotation.z + "\n";


        //Adding Text
        File.AppendAllText(path, content);
    }

Level generator data is nothing but a custom class which i have created to make my code look modular.


public class LevelGeneratorData
{
    public string name;
    public Vector3 position;
    public Vector3 rotation;
}

This creates a tile on to the scene view and simultaneously stores its location and rotation to the text file.


Now the question "How do you read that file and generate the level on runtime?" comes.

For that i have created a script ReadingFileTemp.css. I have used StreamReader class to read text file.

Here is my code :


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class ReadingFileTemp : MonoBehaviour
{

    string path;
    StreamReader reader;
    public char[] seperators;

    string[] array;

    public string levelNumber;
    string levelName;
    void Start()
    {
        // levelGenerator("/Level1.txt");
        levelName = "/Level" + levelNumber + ".txt";
        levelGenerator(levelName);
    }

    public void levelGenerator(string levelName)
    {
        path = Application.dataPath + levelName;
        reader = new StreamReader(path);

        Debug.Log(reader.ReadLine());

        while (!reader.EndOfStream)
        {
            levelGenerator_Function();
        }
    }


    void levelGenerator_Function()
    {
        Debug.Log("CALLED");
        array = reader.ReadLine().Split(seperators);

        Vector3 _pos = new Vector3(float.Parse(array[1]), float.Parse(array[2]), float.Parse(array[3]));
        Vector3 _rot = new Vector3(float.Parse(array[4]), float.Parse(array[5]), float.Parse(array[6]));
      
        GameObject _temp_object = Instantiate(Resources.Load<GameObject>(array[0]), _pos, Quaternion.Euler(_rot));


        //Getting name right
        if (_temp_object.name == "PortalsRed2(Clone)")
            _temp_object.name = "PortalsRed2";

        if (_temp_object.name == "PortalsRed1(Clone)")
            _temp_object.name = "PortalsRed1";
    }

}
 

So as we have stored objects onto the text file in the below format:

objectName: posX,posY,posZ,rotX,rotY,rotZ..... so i have read each line in the text file using ":" and "," as spectators.


Drop me a mail and i can answer any of your questions!! :)

Hope this helps. Thank you. :)


 
 
 

Recent Posts

See All

Comments


bottom of page