#What's the best way to render tile chunks?

1 messages · Page 1 of 1 (latest)

ebon quiver
#

I've got a program that renders tiles based on chunks. Every tile in the given map is represented by a multidimensional array called worldTiles with the custom struct called TileData and the script that categorises them into their respective chunks works fine as they're thrown in a separate 2D array of public GameObject[] worldChunks.

My question is what the best way to render individual chunks is. For context, below is my implementation of chunk generation

public void GenerateChunks()
    {
        // Generates chunks according to worldsize. Current chunk size is 16x16
        int chunksX = worldSize / chunkSize;
        int chunksY = worldSize / chunkSize;

        worldChunks = new GameObject[chunksX * chunksY];

        int index = 0;
        for (int cy = 0; cy < chunksY; cy++)
        {
            for (int cx = 0; cx < chunksX; cx++)
            {
                GameObject chunk = new GameObject($"chunk_{cx}_{cy}");
                chunk.transform.parent = transform;
                worldChunks[index] = chunk;
                index++;
            }
        }
    }

The tiles become children of a parent GameObject with the corresponding chunk category - for example, there would be Chunk_0_0, Chunk_0_1, etc. Until it enters a new row.

I haven't really updated my PrintTiles function actually, so this is it for now:

public void PrintTiles()
    {
        int chunksX = worldSize / chunkSize;

        for (int x = 0; x < worldSize-1; x++)
        {
            for (int y = 0; y < worldSize; y++)
            {
                TileData t = worldTiles[x, y];

                GameObject newTile = new GameObject($"tile_{x}_{y}");

                // classify each tile to its corresponding chunk by categorising the coordinates

                int chunkX = x / chunkSize;
                int chunkY = y / chunkSize;

                int chunkIndex = chunkY * chunksX + chunkX;

                newTile.transform.parent = worldChunks[chunkIndex].transform;

                SpriteRenderer sr = newTile.AddComponent<SpriteRenderer>();
                sr.sprite = tile;
                
                if (t._tileType == TileType.Grass)
                {
                    sr.color = Color.green;
                } else if (t._tileType == TileType.Water)
                {
                    sr.color=Color.blue;
                }

                newTile.transform.position = new Vector2(t.posX + 0.5f, t.posY + 0.5f);
            }
        }
    }

I know there are some implementations for rendering chunks, but I don't know what the "best" method is. As of right now, my world is a 160x160 map (because my chunks are 16x16 and I'm honestly too lazy to write a whole separate script in order to prevent Indexing errors, and this works fine anyways) and I want to create a bigger map in the future without having to render all GameObjects at once.

The reason for me asking this question is because I know there are some inefficiencies when it comes to tile rendering, such as the player moving back and forth and triggering the chunk load/unload, as well as me being relatively new to the Unity editor but simultaneously having a good chunk of experience with things outside of GameDev such as Python and C for OOP and some more "low-level" programming compared to languages like python, so I'm wondering if there's a best practice for this so I don't run into headaches in the future.

Help is much appreciated!! ^^

stiff jacinth
#

The semi-best solution is always using the tools that the engine provides you.
In case of 2d tiles, it's the unity tile map which is very efficient in rendering 2d tiles.

The next best solution is rolling your own implementation based on the tools that unity provides(modifying the tile map via code for example). But you usually don't need the next best solution, as the semi-best solution is usually more than fits the requirements of your project.

In any case, there's the case of overengineering and premature optimizations - don't assume that you have a problem, until you actually have it(or can test and confirm that there will be). In that case, you profile, identify bottlenecks and consider the best options for solving them.

ebon quiver
stiff jacinth
#

Definitely not. I'm not even sure unity can batch sprite renderers. Tile maps are rendered in one draw call. There should be huge difference on the cpu side. Not to mention that you would be able to avoid the overhead of creating objects/components and moving them around.