- Home /
How can I make a Terraria Style game from sprites without using an enormous amount of gameobjects?
![alt text][1]Ever since I played the game Terraria I wanted to recreate it in Unity. My idea was instead of having a huge 10000 by 5000 grid of game objects for tiles (which would be insanely laggy) I would instead have a smaller grid of chunks that would load a per say 100x100 grid of tiles all of which would be one game object just when I attempt to mine in the chunk I would be calling a chunk update function in the one chunk I mined in. This could limit the amount of game objects rendering onscreen used for the game world to a sizable two digit number. I understand Perlin noise and how to use it to make the terrain. The main problem I am having is how to make one game object have a sprite renderer that renders a chunk of tiles. I understand how to isolate individual sprites from a sprite sheet but this seems like I want to compile a 100x100 grid of sprites as one sprite to create terrain chunks and then be able the edit the larger sprite to remove or add the smaller tiles in order to create the terraria style mining and building. Any Ideas on how to create this system would be awesome. I work in C# but I am not a professional, I like to give myself a challenge.
The attached image is just a reference image but others can be googled. [1]: /storage/temp/103996-terraria-caratula.jpg
Stop thinking about sprites. Think about tiles. Your terrain chunks will be gameobjects with a meshfilter and meshrenderer. You generate the mesh by code, tile by tile with simple nested for... loops. Your terrain information is stored in a collection of sorts, for example a two-dimensional array with a Tile class that holds all neccessary information as the array's element.
public class Tile {
int contentID = 0;
}
public Tile[,] tiles = new Tile[16,16];
for(int x = 0; x < tiles.GetLength(0);x++) {
for(int y = 0; y < tiles.GetLength(1);y++) {
tiles[x,y].contentID = random(0,2);//randomly make the content ID 0 or 1.
//for example, 0 is empty and 1 is earth.
}
}
for(int x = 0; x < tiles.GetLength(0);x++) {
for(int y = 0; y < tiles.GetLength(1);y++) {
//generate one quad for the mesh by using the x and y values as cordinates for one of the corners
}
}
This doesn't uses chunks but shows the basic idea. You could use a tilemap and map each tile's quad's UV coordinates to it so it shows the correct tile graphic.
Shouldn't this be promoted to be an answer?
Answer by Vanilla-Plus · Oct 19, 2017 at 03:13 AM
What you're after is known as a 'procedural mesh'! Basically the trick is to just have one modular mesh (chunk) that contains all your grid/matrix/tile data and then update it as the player edits it. Of course for optimization, you would want to have multiple 100x100 chunks or whichever size works best.
There's a brilliant tutorial by Catlike Coding which will run you through how to make a basic procedural mesh here, but you'll need to be a bit creative when it comes to identifying different tiles.
Thanks for the help, I will be testing the solutions further over the next couple days.
I've been testing out the catlike coding thing you messaged and the procedural mesh works great but I'm still fuzzy on how to interact with the mesh and how to apply different textures to different tiles. Anymore help would be great but if you feel that's enough help don't hurt yourself hunting for solutions.
Thanks- @ChiefBreakeverything
To assign different texture to some triangles you separate them into different mesh (which would use material with different texture) OR you pack all textures into single atlas and just move UVs around.
Answer by andrew-lukasik · Oct 25, 2017 at 08:44 AM
If you would manage to write your game such every tile lives completely outside the scene, in some big array data format for example, then Graphics.DrawMesh || Graphics.DrawMeshInstanced can help you limit GameObjects needed to render all these tiles to 0 (well ok, 1).
Idea here is to avoid mesh re-construction step every n-frame and just use single mesh (quad), and draw it in world position of every visible tile. Different material can be used here to represent different tile type.
Write your own collisions etc. on top of that and you will need little GameObjects indeed to run your game.