19
\$\begingroup\$

I've been digging through the documentation on the Tilemap feature of Unity 2017.2.

Does Unity limit the maximum number of tiles it will support for a particular tilemap mesh?

I know that each tile is instantiated once and used to texture the quads on the Tilemap mesh at runtime, so I would guess that the mesh quad count limit is ultimately dependent on the hardware, and more or less is arbitrarily high.

Is that a correct assumption, or is there a hard cap in the engine?

\$\endgroup\$
0

1 Answer 1

29
\$\begingroup\$

Your RAM is your limit.

The following tests were performed on a system with these specs:

  • Intel i5-6600
  • 16 GB RAM
  • NVIDIA GeForce GTX 1070
  • Windows 7 Home Premium

Here is a script I ran which grows a tilemap by filling it with a single tile (32x32 pixels). The Method Grow() adds another column and another row to the current map. The method gets called 100 times each update.

public class TileTest : MonoBehaviour {

    public Tile tile;
    private Tilemap tilemap; 

    public int currentSize;


    void Start () {
       tilemap = GetComponent<Tilemap>;
        Grow();
    }

    void Update() {

        for (var i = 0; i < 100; i++) {
            Grow();
        }
        Debug.Log(currentSize);        
    }

    private void Grow() {
        for (int x = 0; x < currentSize; x++) {
            tilemap.SetTile(new Vector3Int(x, currentSize, 0), tile);
        }
        for (int y = 0; y < currentSize; y++) {
            tilemap.SetTile(new Vector3Int(currentSize, y, 0), tile);
        }
        tilemap.SetTile(new Vector3Int(currentSize, currentSize, 0), tile);

        currentSize++;
    }
}

After a few minutes, my computer ran out of memory and Unity crashed. At that point it was at 8400x8400 (70 million) tiles and Unity.exe was consuming slightly above 11 GB of RAM according to the task manager.

Well, but what about sparse maps?

Here is a different script which placed a single tile at increasing x and y coordinates in increments of 100 tiles:

public class TileTest : MonoBehaviour {

    public Tile tile;
    private Tilemap tilemap; 
    public int currentSize;


    void Start () {
        tilemap = GetComponent<Tilemap>();
    }

    void Update() {
        tilemap.SetTile(new Vector3Int(currentSize, currentSize, 0), tile);
        currentSize+= 100;
    }    
}

The memory footprint of Unity.exe in fact increased very little, which hints that empty tileset cells require almost no RAM. However, the FPS kept falling as the tileset was growing. It hit 60 Fps at 30000x30000, 30 Fps at 60000x60000 and 15 Fps at 90000x90000. The Fps stayed that low when I removed the script while the test-game was running. So this slowdown was not from changing the tilemap. It was simply from rendering it. So when you want to create a really huge open world game, you might have to use multiple smaller tilemaps which you create and destroy at runtime.

Conclusions: Huge but mostly empty tilemaps do not use much RAM, but they are a rendering bottleneck, even when most of it is not in the camera viewport.

I then experimented with this script which generates tilemaps with a given size:

public class TileTest : MonoBehaviour {

    public Tile tile;
    public int xSize;
    public int ySize;

    void Start () {
        Tilemap tilemap = GetComponent<Tilemap>();

        for (int x = 0; x < xSize; x++) {
            for (int y = 0; y < ySize; y++) {
                tilemap.SetTile(new Vector3Int(x, y, 0), tile);
            }
        }
    } 
}

I used this script to generate a 8192x8192 map. It took a few minutes, but when the script was finished, it ran at steady 95 Fps.

Conclusion: Maps with millions of tiles are feasible, at least on gaming PCs.

\$\endgroup\$
9
  • 7
    \$\begingroup\$ This is the most beautiful answer I've seen in a long time. "Lets find out!" writes scripts to hammer the system runs script computer starts smoking "Looks like it doesn't limit you!" Thanks @Philipp! \$\endgroup\$
    – Stephan
    Nov 17, 2017 at 17:51
  • \$\begingroup\$ What was the framerate during the generation of the 8192^2 test? I'm curious how much the generation efforts bogged down the system. \$\endgroup\$
    – Stephan
    Nov 17, 2017 at 21:45
  • 1
    \$\begingroup\$ @Stephan Zero FPS. As I said, the generation takes several minutes. And because this script doesn't leave it's Update-method during the generation, the game and the Unity editor freeze until the generation is finished. If you want your game to be responsive during the map generation, move the generation to a coroutine which generates one chunk at a time and yields between them. \$\endgroup\$
    – Philipp
    Nov 17, 2017 at 21:46
  • \$\begingroup\$ @Stephan And by the way, it might be faster to use SetTilesBlock to set all the tiles at once. But generating the test map quickly wasn't my goal here. \$\endgroup\$
    – Philipp
    Nov 17, 2017 at 21:53
  • 1
    \$\begingroup\$ @Philipp - I finally found a few free minutes to give this a try (after upgrading unity to 2019.3.11) In the previous version, loading the tilemap with 240x180 took over 10 seconds. In the new version, it took just 0.185 seconds! I'm also getting a framerate of 1500 - 2300 FPS. \$\endgroup\$ Apr 24, 2020 at 19:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .