Search Unity

Runtime Access to Unity 2d Tiles

Discussion in '2D' started by GeorgeStevens, Jun 23, 2021.

  1. GeorgeStevens

    GeorgeStevens

    Joined:
    Jul 3, 2020
    Posts:
    3
    4
    I'm trying to use Unity's 2017 tilemap features. What I would like to do is push a tile's sprite up (change its offset), so that the sprite moves up pixel by pixel and the top of the sprite loops (wraps) back around to the bottom. Basically, I want to animate my "Water" sprite without having to build 20 different versions of the sprite to achieve the same effect. I was able to do this in Rotorz tiles by accessing its Atlas' MainTexture Offset or something like that but this product is discontinued. This animation is similar to the water in classic RPG games like Ultima 4.

    More than that, I would just love to have runtime access to the tiles to do other things: change out the entire sprite on a single tile, change the color, etc.

    I have made a custom Tile class using this example: https://docs.unity3d.com/Manual/Tilemap-ScriptableTiles-Example.html

    But this only seems to affect tiles at the time of placement.

    Is this possible and does anyone have a good example? Docs on this feature are scarce.
     
  2. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    570
    when you change a tile that has already been placed you have to RefreshTile or SetTile on the position of the tile
     
  3. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,514
    Try this:
    Code (CSharp):
    1. var m = Matrix4x4.TRS(new Vector3(0, Mathf.PingPong(Time.time, 1f)), Quaternion.identity, Vector3.one);
    2. tilemap.SetTransformMatrix(cellOfSomeWaterTile, m);
    What this does is set the Matrix of the tile, pingponging the position.y-value up and down over time.

    The tilemap has access methods for you to change the data associated with the Tile. The tile and its TileData are separate. The TileData includes the matrix, color, flags, and other info. However, one thing you don't have access to via the tilemap is the sprite; control of that is left to the Tile in its GetTileData() method.

    See the setter methods here:
    https://docs.unity3d.com/ScriptReference/Tilemaps.Tilemap.html

    That said, there's probably a better way to do this:
    Code (CSharp):
    1. waterTilemap.transform.position = new Vector3(0, Mathf.PingPong(Time.time, 1f));
    If you have a dedicated water tilemap, you could move the whole tilemap up and down. Depending on what you want, this may be preferable because it would eliminate the need to track which cells within a tilemap have water, and it would be more performant.
     
    Last edited: Jun 23, 2021
  4. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,514
    And one more way to do this: a vertex shader. You could use a shader to move up and down the vertices of your water sprites over time.