Runtime generation and tilemap collider


I’m generating my tilemap at runtime by using Tilemap.SetTile(), and I’m using raycasts for collision detection, which works just fine. I managed to re-generate the tilemap collider by disabling and enabling the Tilemap Collider 2D component, although I would prefer if there was a dedicated method for doing this (I couldn’t find one).

This all works fine when running within Unity. However, when I build the project for Windows and run the exe-file, my character just falls through the platform as if the tilemap collider didn’t exist. I also get the following error message, which might be related:

“Sprite outline generation failed - could not read texture pixel data. Did you forget to make the texture readable?”

Do you have any idea what’s causing this?

Here’s the script I use to generate the platform:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Tilemaps;

public class DrawTilemap : MonoBehaviour {

    public Tilemap tilemap; // The Tilemap component on the gameobject where the platform should be drawn
    public TileBase tile; // The tile sprite (TileBase) to be used to draw the platform

    // Use this for initialization
    void Start () {
        GenerateWorld ();

    void GenerateWorld () {
        // Create a 10x10 platform of tiles
        for (int x = -5; x < 5; x++) {
            for (int y = 0; y > -10; y--) {
                tilemap.SetTile(new Vector3Int(x,y,0), tile);

        RefreshCollider ();

    void RefreshCollider () {
        // Update the tilemap collider by disabling and enabling the TilemapCollider2D component. This is the only solution I found to refresh it during runtime.
        tilemap.gameObject.GetComponent<TilemapCollider2D>().enabled = false;
        tilemap.gameObject.GetComponent<TilemapCollider2D>().enabled = true;
1 Like

There’s a bug in the TilemapCollider2D not regenerating the tile collision shape when the tile changes which will be fixed. Disabling/Enabling obviously regenerates the whole tilemap as a workaround but as you probably know is expensive.

As to the other issue; I’m not sure what’s going on there so I’ll pass it onto the 2D guys involved in the sprite stuff.

1 Like

Thanks for the info!

Yes, I noticed it was quite expensive, but physics usually are, so I was planning to split the map into chunks of multiple Tilemap gameobjects so I only have to update the collider on a smaller area if the player changes one tile.

Something that would help is a feature that automatically splits the collider into multiple chunks if requested, with the possibility to specify chunk size yourself, so you can choose if you want to optimize draw calls (larger chunks) or runtime generation (smaller chunks). But that’s somewhat of a luxary feature, so probably shouldn’t have highest priority.

If you make the collider always update itself when a tile changes, it would be nice with some way to add tiles in batch without updating the collider, for when you’re procedurally generating large areas at once (although I guess you could just delay adding the TilemapCollider2D component until after you’re done).

Please tell me if you need any more info about my problem. Like I said, it works just fine within Unity, but when exporting the project and running it outside of Unity in Windows, the collider won’t regenerate, even if a disable and enable the TilemapCollider2D component through code. Not sure if it’s related to the sprite error message or not. The Tilemap itself without the collider seems to generate just fine through code, even in the exported project.

You perhaps misunderstand; when you change a tile, it doesn’t need to recreate the whole collider, just the shape for that tile (either removing it or adding a new one). The TileMapCollider2D just creates a Box2D shape for each tile and we can update each one separately. Enable/Disable does all of them.

I’ve passed on the other problem to the 2D guys involved in the sprite stuff. The problem will lie there and not with the collider which obviously cannot create the shapes without the sprite outline data.

1 Like

Ahh, I see. That sounds nice, then maybe I won’t need as much chunk division as I thought once the TileMapCollider2D regenerates correctly.

Thanks for forwarding it. Hopefully they can see what’s wrong. If they can’t recreate it I can try to upload the project.

When you assign a sprite to a tile, the TileMap can render the sprite. If you also have the tile set to use ColliderType.Sprite then the TileMapCollider2D will be asked to create a collider-shape from that sprite. It’ll first check the sprite to see if you’ve created an explicit sprite outline in the sprite editor for it. You should always try to do this as the fallback is to require the texture is readable and create an outline from that.

Textures are always readable in the Editor but are not outside of it. To set them readable you need to explicity select that in the Texture Importer however this is far less desirable as it means those textures are kept in memory.

Use the Sprite Editor to create and tweak sprite outlines and you should be fine.

1 Like

Ahh, that explains it! I was a bit unsure how to correctly handle tile collision setting, so I didn't create an outline manually, and noticed it worked anyway in the editor. But now I know. Thanks for the information!

1 Like

Hi! I'm having the same problem using 2017.2 (update tile on the fly). It's been already fixed?

I’m encountering the same issue here a year later. Procedural tiling is very important for my game; can we please get an update?

1 Like

Instead of setting Read/Write Enabled for your Texture2D, you can set Generate Physics Shape for your Texture2D of your Sprites. This will generate and store a Physics Shape based on the outline of your Sprite which will be used for your Tiles in the TilemapCollider2D in the built player.

Let us know if that is suitable for you with your usage of procedural tiling!

Bump: just ran into this same problem. Changing a Tilemap via SetTile() doesn’t seem to update its TilemapCollider2D on the fly. The workaround of manually toggling the collider’s enabled from false back to true worked for me.

For anyone who ends up here trying to work with procedurally generated tilemaps that use a collider, what you want is the TilemapCollider2D.ProcessTilemapChanges method. This will update the TilemapCollider2D immediately.

Tried all of the solutions mentioned here, none of them work:

DungeonCollisionmap.GetComponent<TilemapCollider2D>().enabled = false;
DungeonCollisionmap.GetComponent<TilemapCollider2D>().enabled = true;
DungeonGo.SetActive(true); // All manner of toggling the game object has no effect either

I’ve got one tilemap that was created in the editor that works, and one tilemap that was created at runtime where collisions don’t work.

1 Like