Search Unity

Official 2D Tilemap Extras 2.0 released for Unity 2021.1

Discussion in '2D' started by rustum, May 10, 2021.

  1. danyaegoist

    danyaegoist

    Joined:
    Nov 8, 2017
    Posts:
    7
    I have copy code from Unity classes. It's not my code. My code is strongly cached.
     
  2. danyaegoist

    danyaegoist

    Joined:
    Nov 8, 2017
    Posts:
    7
    Some of the best solution will be add some sort of shadow tilemap(Like shadow DOM in html). We working like with standard tilemap, and on update it will updated, recalculated etc and applied on the real tilemap.
     
  3. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    1 & 2.
    I do not think the Tile assets are boxed or that the Tilemap.Set* APIs generate GC allocations (Outside of Mono Jit). The Object here would is actually UnityEngine.Object rather than System.Object. If the Tilemap.Set* APIs or other APIs do generate GC allocations which you do not expect, do let us know and we will investigate.

    3.
    Could you describe the Tile Pooling system further? We would like to know more how this could be used by you and other users. Thanks!
     
  4. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, you are right. We will fix this. Thanks for letting us know!
     
  5. danyaegoist

    danyaegoist

    Joined:
    Nov 8, 2017
    Posts:
    7
    Thanks for your reply.

    1. I had suspicions of memory allocation in those cases when I move to the side and draw tiles on new positions, and clear them from behind. Those. we create new ones, and old ones release memory. What is the best way to act in such a situation? I can't pooling tiles from the outside in any way. I'll test it more for sure. But what do you think?

    2. As I see it so far. a nice implementation of a lazy single tile assignment that will collect all changes and apply them at the end of the frame.
    Example: We are redrawing the entire screen (clearing off-screen tiles and drawing new missing ones) and don't want to create an array to update the package. Very difficult with this side on our side without any highlights. I don't store the map anywhere, and usually the seed for building the map structure by layer at runtime.
    In my case, there will be a method that receives a single SetTile request but does not update the view. If the tile has not changed, then it does nothing. And two separate methods for recalculating tiles for implementations (for example, Tile Rule) and a separate one for redrawing. Perhaps it would be convenient to implement lazy application directly in the data of a particular tile by adding "a new tile that will be applied when drawing", so that you do not have to store an array of changes somewhere.
    It would also be convenient to clear tiles that are not included in target region (int x, int y,int width,int height).
    These two things made my script 80% smaller.
     
  6. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Could you share how you are adding and clearing new Tiles? Using the Unity Memory Profiler could help track where the GC allocations are coming from, and we could figure out how to reduce these allocations.

    We will consider this, thanks! This may make the usage of the Tilemap more complicated as users will need to consider which Tiles have been recalculated immediately or a future time.

    I am not sure if this will work out for you, but you could try the following to clear Tiles:

    Code (CSharp):
    1. tilemap.origin = new Vector3Int(x, y, 0);
    2. tilemap.size = new Vector3Int(width, height, 1);
    3. tilemap.ResizeBounds();
    This should allow you to refit your Tilemap without using SetTiles to clear Tiles. You would still need to call SetTiles to add new Tiles.
     
  7. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    78
    Not entirely about "extras", but is there a way to refresh a tile when any tile below is refreshed?

    Basically, I made a tile which checks tile below it and sets own sprite and transform based on that. I need to call refresh for this tile when tile below is refreshed to make sure they are synched properly, but there is only Tilemap.tilemapTileChanged event available (which is not called when previewing tiles too).

    My guess is that I have to use custom tile classes for everything that will call my own events, but is there some plans to expand what can be done with built-in functions if what I want is not avilable right now?
     
  8. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    You would likely need to write your own custom Tile class to do so. By default, the Tile class would refresh only its own position, while the RuleTile class would refresh its own position and its neighbouring positions. Tilemap.tilemapTileChanged is triggered only when an actual Tile has changed rather than a preview.

    Would it be possible to share what you would like to do? We could expand Tilemap.tilemapTileChanged or introduce a new callback for previewing if it is suitable for user workflows.
     
  9. GamerXP

    GamerXP

    Joined:
    Mar 22, 2014
    Posts:
    78
    Yes, I've implemented it with custom tiles for now: other tiles now call custom Referesh event when they update their data, and I subscribe to it for now.

    About what I needed that for:

    I have a "shore" tile, and then I have "waves" tile which is supposed to be put on top of shore tile. They are separated because I animate waves with a shader. "Waves" tile got a sprite for each sprite varition "shore" has, so I'm looking at the tile below "waves" and select a matching sprite.

    At first, I wanted to just spawn those at runtime with game objects, but then I got a need for more control over where "shore" tiles are put, so I'm placing them in editor mode in the end. I also tried to make "waves" as similar rule tile, but then it didn't work when there are 2 opposide-facing shores nearby.

    As for "Tilemap.tilemapTileChanged", I'd like it to return what tile was in the cell before the change.
     
  10. wechat_os_Qy0xDfW7_FXo5lVaICGD12FD8

    wechat_os_Qy0xDfW7_FXo5lVaICGD12FD8

    Joined:
    Jul 9, 2023
    Posts:
    6
    I want to update multiple tiles in a single call, the method I found is
    Code (CSharp):
    1. SetTiles(Vector3Int[] positionArray, TileBase[] tileArray)
    , But it did not support offset and length, which means If the size of array of tiles I'm going to update is dynamic that I need to create a new array every time I call the SetTiles. The method I needed is like this
    Code (CSharp):
    1. SetTiles(Vector3Int[] positionArray, TileBase[] tileArray, int offset, int length)
    and what I will do is only create a array with maximum possible length and then I will pass the offset and length if I only want to update a subset of the array