Search Unity

Bug Unity having a hard time with tilemaps with a lot of tiles in a prefab ?

Discussion in '2D' started by aDaxxas, Jun 14, 2020.

  1. aDaxxas

    aDaxxas

    Joined:
    Aug 7, 2015
    Posts:
    11
    Hello,

    So here is my issue : while editing tilemap in a prefab, when I'm starting to have a lot of tiles placed (about that much :

    My unity starts going crazy when I place more tiles (profiler screenshot : https://i.imgur.com/BMMj8MJ.png)

    I have auto save off, and I do have a script with an OnValidate function in the prefab, but removing the function doesn't change things enough to see a change.

    I want to precise that I have no issue when having a lot of tiles in a tilemap in a scene, the issue is there only in prefab mode.
     
  2. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, the profiler screenshot does not have enough information shown to see what is taking up all the processing time. If you could share the profiler data by saving the profiled information (there is a Save button on the toolbar of the Profiler), that would be helpful! Alternatively, expanding the hierarchy for the slow portions and sharing that screenshot here would help too!
     
  3. aDaxxas

    aDaxxas

    Joined:
    Aug 7, 2015
    Posts:
    11
  4. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Thanks! We will check out the profiler data first!
     
  5. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, sorry for the late reply! It seems that most of the time spent in spent flushing changes you have made and writing back data. Unfortunately, that does not help us to pinpoint if the time spent doing this is expected.

    If still possible, could you share the project? Possibly through the Unity Bug Reporter and posting the case number here? Thanks!
     
  6. aDaxxas

    aDaxxas

    Joined:
    Aug 7, 2015
    Posts:
    11
    Sorry for the late response (I hope not too late)

    You can find my projet on github here : https://github.com/Daxxas/CaveRunner
     
  7. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Thanks! Will check this out!
     
  8. aDaxxas

    aDaxxas

    Joined:
    Aug 7, 2015
    Posts:
    11
    Did you had time to check it ? If so did you notice anything ?
     
  9. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, it looks like you are using deeply nested prefab for storing your Tilemap as a prefab. Ideally, you would be editing the Tilemap in Prefab mode at a level where it does not belong to any other prefab for performance reasons. Each time you edit a Tilemap at a higher level of the nested Prefab, it will need to sync and detect changes with the lower levels of the nested Prefab, causing the performance issues you see. If you try unpacking a Tilemap prefab in the Scene view completely, convert it back to a single level Prefab and try editing it in Prefab mode, you will have better performance with this.

    Is there a reason you need to have the Tilemap nested at multiple levels?
     
  10. vvvey

    vvvey

    Joined:
    Aug 13, 2016
    Posts:
    7


    Hi there,

    Sorry for the necro-post, but I'm having the exact same problem and I think I have a good reason to use nested prefabs with tilemaps the way I'm doing. That is unless you can suggest a better practice for achieving what I describe below.

    When working with tilemaps you'll usually have a lot of layers that you want to work with. Let's, for example, say that I have a floor layer, a wall layer, a ceiling layer and maybe some other layers for putting details on the wall and floors. See example below.




    In my game I have made a custom editor where, after importing a tileset, I can edit the layer of any given tile. This is then stored on my Tile ScriptableObject.

    In the editor I then proceed to use a custom brush and override the OnPick method to pick the correct tilemap object to draw on. This way I don't have ever have to manually switch the tilemap object when picking a tile for a specific layer.






    See the above screenshot; the way I've set it up is


    • Sewers1 is an instance of the prefab MapTemplate
    • MapTemplate contains an instance of the prefab TemplateTileMapStack along with some intelligent defaults like map entry and map exit points
    • TemplateTileMapStack contains a bunch of layers as is seen in the screenshot. Each layer has a couple of common scripts, for example my TileLayerRepresentation script which handles movement of tiles when resizing the map. The CeilingLayer and AutoGeneratedWalls layers have colliders to prevent bullets from going through them etc.
    This enables me to change the properties of any given layer once and have that change get propagated automatically to all of my tilemaps. It also lets me add a layer to all tilemaps whenever simply by adding it to the TemplateTileMapStack. So process work my workflow is


    All tilemaps in my game are saved as prefabs that are then loaded into a game scene in order to not duplicate the contents of this game scene everywhere.



    1. Import tileset (creates a custom tileset object with various properties and editors for editing the terrain of all tiles)
    2. Edit the terrain of the tiles
    3. Create instances of the MapTemplate and configure the parent object with a music track, a darkness level and some other gameplay settings specific for the map.
    4. Use the custom brush to automatically paint tiles on the tilemap associated with their layer

    This workflow is intended to simulate that of RPG Maker 2003 (I used that heavily as a teenager :) ) which is highly efficient. Also, it easily allows me to extend the tile information with a terrain setting so that in the future I can easily add different footstep sounds to different terrains in my game (it's a stealth game so kind of important).


    This is quite dependent on the nested prefabs to work. Is there a better practice I can use to achieve the same thing with better performance? If not, what's the recommended approach?

    Also, I must point out that in Unity 2019 and earlier, the performance was decent. The editing had some lag spikes on older computers, but even my 2014 macbook pro with the 2,2 ghz i5 could handle it well. My desktop with an i7 8700 has even fewer problems.

    But after upgrading to unity 2020 it takes 20+ seconds to open bigger levels, and editing the maps is a terrible experience. On a slower computer it can even take 3-4 minutes to open these maps (from when I click Open Prefab).


    edit: I just noticed that dragging one of these maps into the scene view instead of editing them as a prefab was almost instant in terms of loading time. Unfortunately my scripts are built around the prefabstage but might be possible to change. However, this should indicate that reading and managing tiles from a bunch of nested prefabs might not be the problem, but the prefab stage editor itself. Any thoughts on that? Performance for adding tiles is nasty that way though
     
    Last edited: Oct 18, 2020
  11. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    There have been some changes to make this a little faster for handling Tilemap Prefabs in Unity 2020.2, but that may take a while to leave beta. There will still be a editing performance penalty due to the nature of how the Tilemap is serialized in Prefabs.

    Would it be possible to share your project to see if the changes will help with your usage of the Tilemap? You could do that by filing a bug using the Unity Bug Reporter with your project and posting the bug case number here. We will try to see how we can improve this internally or mitigate the problem through workflow changes.

    If not, sharing profiler screenshots or data dumps of the slowness when opening or editing levels could help us find out more of the bottlenecks you are facing.

    Thanks for your help in this!
     
  12. vvvey

    vvvey

    Joined:
    Aug 13, 2016
    Posts:
    7
    Hi Chuan, thanks for your fast reply!

    I've made the report and attached the project along with reproduction step. Check out case 1285930.
     
  13. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Thanks! Will check it out!
     
  14. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    811
    Hi!

    I am also having serious issues with this. I want to be able to have a tilemap as a prefab and then use that tilemap in different scenes, but each scene has different tiles painted on it. This way, if I want to change something about the tilemap or add a script, it will be done through the prefab and happen in every level. However, it is super slow painting the tiles this way that it makes it impossible to work with.

    I unfortunately have to resort to having it not as a prefab in every level then, if I need to change something, going through 60+ levels and changing that tilemap.

    Is there anyway to work around this?

    Thanks!
     
  15. TomTheMan59

    TomTheMan59

    Joined:
    Mar 8, 2021
    Posts:
    356
    @ChuanXin Was there ever anything done? The post above is something needs some serious attention if possible :(

    I appreciate all the hard work!!
     
  16. theforgot3n1

    theforgot3n1

    Joined:
    Sep 26, 2018
    Posts:
    208
    I'm also experiencing this issue just now. Having huge performance hits when working with a prefab that is nested twice (in my case nested this way: there is a Level tilemap, which contains a grid, which contains the tilemaps themselves.

    I also really like the flexibility of not having to change all tilemaps if I want to change some common aspect. I have a theory that you can use prefab variants to do this. Although, there will still be some performance hit I suspect... gonna try it out and see how it goes.
     
    MousePods likes this.
  17. theforgot3n1

    theforgot3n1

    Joined:
    Sep 26, 2018
    Posts:
    208
    So the prefab variant structure does work sufficiently in my case. Again, my structure looks like this

    1. Root prefab
    2. Grid prefab
    3. Tilemap prefabs

    What I've done is change it to

    1. Root prefab
    2. Grid prefab variants
    3. Tilemap prefabs inside of the grid prefab variants

    I made a prefab variant out of the grid prefab, which allows me to override the tilemap prefabs in each variant of the grid prefab. While editing the grid prefabs, I do have a significant performance hit. But it's still way more manageable than what I had when trying to override the root prefab with tilemap modifications. After finishing my edits of the grid prefab variant, I go back to the original scene with the root prefab where performance is way, way better. This works in my case.
     
  18. waishan

    waishan

    Joined:
    Feb 27, 2021
    Posts:
    2
    When the tilemap prefab is nested within prefab, the serialization is different, which caused my meta file to become very large. (Three times larger than if I use tilemap directly in prefab. And the size of the meta file basically does not decrease when the tile is erased.)

    I don't know whether it is affected by this, my component inspector has become slow.I failed to find the reason and I only found this situation in large-sized prefab.

    So I tried to store tilemaps in the template, and copy and sync it to the level prefab via a script. As a result, every time template was changed, each level prefab has a change record.
    It's going to take a little bit more work, but once the layer structure is stable, changes will become less. And I prefer nesting prefab to unify the layer structure of tilemaps.:confused: