- Home /
Create level based on XML/TXT file
Hi everyone!
I'm new to unity and was thinking about a nice concept of creating levels based on an XML/TXT file.
Let's say I have an file which looks like this:
X X O X
X O X X
X X X X
X X X O
I want to create a grid (underground) from this file. For every X I want to load an area on which it is possible to walk. For every O it should load an obstacle, which cannot be passed.
Is this possible to do? Or are there already scripts/implementations which can be used?
Here is an example of how the game should look like:
So I will load also 3D objects according to the marks set. I want to be able to load the underground, holes in the underground, obstacles and also checkpoints.
The idea is to extend the levels further on easily.
I would not know why it wouldn't work. But why do that when Unity is useful for the graphical development tools it has?
This might be more useful when you develop a 2D side scroller in basically any other environment.
I updated my question. So you can imagine what it should look like
Answer by 4ndro1d · Nov 19, 2013 at 06:29 PM
Here is the overall solution for creating an level based on an TXT file:
Textfile looks like this:
S 0 0 0 1
0 0 1 0 2
2 0 0 2 1
We need to read the file and save it's content into an twodimensional array. We will split by line breaks and spaces:
string[][] readFile(string file){
string text = System.IO.File.ReadAllText(file);
string[] lines = Regex.Split(text, "\r\n");
int rows = lines.Length;
string[][] levelBase = new string[rows][];
for (int i = 0; i < lines.Length; i++) {
string[] stringsOfLine = Regex.Split(lines[i], " ");
levelBase[i] = stringsOfLine;
}
return levelBase;
}
In the next step we are going to iterate through the matrix and instantiate the Prefabs we bound to our Script via public variables:
public Transform player;
public Transform floor_valid;
public Transform floor_obstacle;
public Transform floor_checkpoint;
public const string sfloor_valid = "0";
public const string sfloor_obstacle = "1";
public const string sfloor_checkpoint = "2";
public const string sstart = "S";
void Start() {
string[][] jagged = readFile("D:/level1.txt");
// create planes based on matrix
for (int y = 0; y < jagged.Length; y++) {
for (int x = 0; x < jagged[0].Length; x++) {
switch (jagged[y][x]){
case sstart:
Instantiate(floor_valid, new Vector3(x, 0, -y), Quaternion.identity);
Instantiate(player, new Vector3(0, 0.5f, 0), Quaternion.identity);
break;
case sfloor_valid:
Instantiate(floor_valid, new Vector3(x, 0, -y), Quaternion.identity);
break;
case sfloor_obstacle:
Instantiate(floor_obstacle, new Vector3(x, 0, -y), Quaternion.identity);
break;
case sfloor_checkpoint:
Instantiate(floor_checkpoint, new Vector3(x, 0, -y), Quaternion.identity);
}
}
}
}
Here is the result of this. I was reading a 10x10 matrix holding several different strings (just like the mentioned text file):
I hope this will help all you guys for making games with nearly no effort to create new levels. I would also like to thank gajdot who helped me a lot in finding the answer.
You can have multiple correct answer as far as I know, why did you remove $$anonymous$$e if that helped you to make your solution?
Because it was only one part of the solution and this is the whole routine. Also I guess it would be annoying to have to read all our comments. I guess just can accept one answer as correct and in this case it would be this one. I can upvote your answer as soon as I have enough reputation.
$$anonymous$$ight be necroing but shouldn't you use Gameobject? Then you could just add prefabName.transform
ins$$anonymous$$d
No. "GameObjec"t is in most cases the most useless type of an object. If you don't have a custom script you may need on your object, the Transform component gives you more control over common attributes (like the position / rotation of the object).
someGameObject.transform
is actually more expensive than
someTransform.gameObject
or in general
someComponent.gameObject
So in most cases you want to choose the most useful component of your prefab as reference. Then you Instantiate the prefab, the return value will be the same component that you passed in.
For example if you have a "Player" script on your player prefab, you can define your prefab reference as:
public Player playerPrefab;
When you instantiate the prefab you have direct access to the Player script on the new object:
Player inst = Instantiate(playerPrefab);
Would you be willing to describe the full setup you used here? I am trying to do something similar but add in a height option as well. Any ideas?
Answer by gajdot · Nov 18, 2013 at 10:57 AM
Unity now has built in 2d capability, so he may need it. It can be done, even though I didn't saw a pre made script for you so you need to create your own one.
Basically what you can do like in any programming environment is that you create a script to read a file, and interpret what he reads. You create a small prefab with the obstacle and collider. After this you just go trough the file and hold a value for column and row you are reading from the file and basically you instantiate a prefab(if you have x) on a coordinate based on your value read, something like row*sizeOfPrefab, column*sizeOfPrefab else if you have 0 you don't do anything. This way you get a nice grid map made up from your prefab.
You can go even beyond if you do other values and create other prefabs like wood wall, brick wall etc and you instantiate the specific prefab on the coordinate instead of a general one.
Basically this can be used to create a 3d environment too, you just need a 3d prefab in that case and generate floor when you have x, otherwise wall :)
It seems you understood my question best ;) Can you tell me what a prefab is? I also updated my question so you can see what I want to create
T create a prefab you need to create the game object as you want in the scene view, assign materials, textures, scripts what so ever and then just pull it into the project window. There it will create a prefab and your object in the scene will turn blue to notify that that's an instance of the prefab. You can delete your object from the scene view and have the data contained in the prefab. Now to programatically create one, you need to invoke a function in case of C#: Instantiate(brick, new Vector3(x, y, 0), Quaternion.identity); or JavaScript: Instantiate(brick, Vector3 (x, y, 0), Quaternion.identity); You need to link the prefab into the script, so in case of this example create a public gameObject brick variable and drag the prefab from the project view to the inspector view onto the script. If you got this, you just need to read trough the file with two loops and make some ifs or a switch case and call the above function to instantiate your prefab on the given coordinate with the given rotation.
If something is not clear please ask, and I'll answer as soon as I can.
So in case of your example you need prefab for visited, whole with obstacle, whole without obstacle, visible obstacles, finish and checkpoint if you have. And attach appropriate behavior scripts for them. To get the checkpoints logic up and running you need a separate game object to contain all of your checkpoints and activate them based on the given order. If you only have a finish then you just need a script to trigger onTriggerEnter
Thanks a lot for this detailed answers. I will just try and error through this. And I really appreciate this great community :)
You are welcome, if you have any further question just ask :)
Okay I already was able to implement the dynamic level setup :) I will continue with trying to make my cube rotate and move to the next field now
Answer by Shudrum · Nov 18, 2013 at 11:05 AM
It's really simple, for beginning, you create a script with two GameObject vars, one for the walkable tile, the other for the collider tile.
On start, you load your file and with two loop (can't write an entire and real source now) :
for (x = 0 to length)
for (y = 0 to length)
if (file[x, y] == 0) Instantiate walkable
else Instantiate walkable
Thanks for the answers. I will start trying this with a harcoded matrix.
Your answer
Follow this Question
Related Questions
Creating 3D levels with text and XML files 2 Answers
Creating a Level using XML 1 Answer
Can't use System.IO.FileInfo.Delete 1 Answer
A node in a childnode? 1 Answer
Saving gameobjects' properties for Dynamically growing prefabs 1 Answer