- Home /
Instantiate large block maps
Hello everyone
I'll try to keep it simple so I won't annoy you with the details.
In my game, i have a tile-based map system, much like it's done in minecraft, but only one "layer" of blocks. I read the map from text files and create a map class, the map class has a jagged array (array of arrays, or just matrix) in which I store every block in the map. For each "cell" in the matrix I store information for that block, an ID and a refference to the gameObject model the tile should look like (as well as some more data not meaningful for what I am asking).
So the point is, I want to know what is the best way (in terms of efficiency, as well as simplicity) to instantiate the map I've got saved as "data" in a class to my 3d world in unity.
What first came into my mind was to iterate through all the cells in the matrix, instantiating one by one each block (with the Instantiate() method) in the matrix, but I keep thinking there must be a much better and faster way to do this. Am I wrong?
I'd like some advice on that. I'm not asking for any code examples.
Thank you very much!
Answer by robertbu · Jan 24, 2013 at 01:11 PM
One solution for this kind of problem is to use a base tile mesh with a single look and then put a plane on the face of each tile to display an image for the unique aspects of the tile. Think of a playing card where you create one game object that is a blank card, and then have a plane display the texture representing a particular card. The planes use UV coordinates into a texture atlas for display, so all of your 10 x 10 tiles would only use 2 draw calls.
Unity has Texture2D.PackTextures() for creating an atlas, though for something as regular as fixed sized planes, an atlas can be created in Photoshop by hand. Because of the number of triangles, the plane that comes with Unity is not a good choice. Code samples of building a plane mesh can be found if you search Unity Answers, but even easier is to use the CreatePlane editor script. You would still have to set the UV coordinates for each plane in code.
We the EZGUI interface package. It provides tools to automate this process, so we don't have to deal with UV coordinates. Their PackedSprite class allows the author to associate a stack of textures with a single plane. At runtime, any of the textures packed can be selected. Since all the textures are in an atlas, changing at runtime does not increase the drawcalls. I'm sure other interface packages have similar solutions. So for your map, you could create a packed sprite that has the ability to display any map element. Then at runtime based on your text data, just select the desired element.
If the number of games objects causes you a problem (there would be 200 for a 10x10 mesh), you could combine meshes (Mesh.CombineMeshes()), or author the tile base as a single mesh and put the planes on top.
Answer by Setzer22 · Jan 24, 2013 at 11:40 AM
Well, just for the sake of this being answered, I'll auto-answer myself. Any more answers or opinions are welcome as well (I'm not going to mark mine as answered unless nobody else posts here).
As I thought, Instantiating is not an option. Even in a 10x10 map it may cause performance issues on the slower computers (and high number of draw calls as well). What I was looking for was procedural mesh generation. That's more literally: creating the mesh through code. So, instead of a lot of GameObjects, representing tiles, I had to found a way to create a mesh from scratch (and through code). Using submeshes and texture atlases (still don't know the plural for atlas and it seems I'm to lazy to look it up), and nicely placing the UV coordinates, generating a map through code with different tile types is possible. And with one single mesh, the draw calls were greatly reduced.
There might be other sollutions to this. It's more a design issue than an implementation one, so, as I mentioned earlier, any other answers are welcome.
Your answer
Follow this Question
Related Questions
Different array value at different times 1 Answer
How to Instantiate a Different Game Object After Getting to the End of an Array? 1 Answer
Instantiate Game Object on Array of Transforms 1 Answer
How can I Instantiate a GameObject and then alter an array that is attached to that GameObject 1 Answer
How to randomly spawn three non repeating gameobjects from an array? 2 Answers