Search Unity

[RELEASED] Super Tilemap Editor

Discussion in 'Assets and Asset Store' started by CreativeSpore, Feb 21, 2016.

  1. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Hi there, is this a question for the Smart Platform Collider tool?
    In that case, what of the controllers are you using?
     
  2. ury2ok2000

    ury2ok2000

    Joined:
    Dec 29, 2012
    Posts:
    46
    Thanks for the reply, I am using the smart platform collider (sorry is that in a different forum- if so i can copy this question to it instead). I am attaching an image of the relevant components on the player. I simply have the controller/input scripts on the player, the only time i affect the control of the character is on death as described in the original question. It works, but looks a bit janky so not sure if there is a recommended way to go about removing control to enable a rigidbody type reaction to death and then re-enabling it with default/zero values at a starting position. I suppose it might look fine too to remove the player from controlling the character while still using the input/platform collider tool to cause a jump back on death (while playing a death animation).
     

    Attached Files:

  3. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    This controller is supposed to be used without a rigidBody. To control the player physics you need to access the PlatformCharacterPhysics. You can change the velocity or apply an acceleration using this class.
    So, to make the dead effect, I guess it is like Sonic dead effect, you could:
    1. Disable the PlatformCharacterInput component: player.GetComponent<PlatformCharacterInput>().enable = false;
    2. Set y velocity to make it jump. player.GetComponent<PlatformCharacterControler>().PlatformCharacterPhysics.velocity = Vector3.up * 10f;
    If you can, for performance, avoid calling GetComponent using a cache for the components.
    This should work fine, if you have any issue let me know.
     
  4. JSwanFin

    JSwanFin

    Joined:
    Apr 10, 2013
    Posts:
    19
    Any news or estimation on isometric support?
     
  5. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    It's still work in progress. If I have to make an estimation, I hope it will be available during the next weeks.
     
  6. Ryan-Hayle

    Ryan-Hayle

    Joined:
    Feb 16, 2014
    Posts:
    142
    Hi, I build my levels using the tiled editor and import using the tmx import feature. I am using object layers in order to scale my tiles (to have different tree sizes, etc), however this feature is missing with your asset. Would it be possible to add this?
     
  7. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    I will increase the support for TMX eventually, but I am afraid it won't be soon.
    If you want to use tiles with different sizes in Super Tilemap Editor you can use a prefab with the script TileObjectBehaviour attached to it and attach the prefab to a tile. This way, each time you paint the tile, the prefab will be instantiated with the image of the tile where it was attached to and you can change the scale and the rotation as you wish.
     
  8. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore So I have gotten back to using this and still having issue with understanding the proper way to use carpet brushes.

    This is a dirt with grass edge carpet:
    grass-sand-setting.png

    This is the water with sand edge carpet:
    default-setting.png

    Which results in this:
    with-default-setting-example.png

    Other post following to get by the 5 images per post limit
     
  9. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore

    So I tried doing other instead like this:
    other-setting.png

    But that results in this:
    with-other-setting-example.png

    I then also tried to use the group you mentioned like this:
    group-setting.png

    And that resulted in this:
    with-group-setting-example.png

    I also got the same result when putting the dirt / grass brush in the same group as the water / dirt brush.

    I am not quite sure what I am doing wrong here.
     
  10. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Try setting both brushes in autotiling mode Group and use a different group than default to avoid autotiling with other tiles.
    I think you want to use the carpet brush as a Terrain brush. I have a prototype not included in the asset because it has some special cases where it doesn't work as other brushes.
    Just in case it is useful for your case, I have attached the brush here.

    If you have problems setting both brushes to group mode let me know.
     

    Attached Files:

    Last edited: May 30, 2017
  11. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore So I set both the dirt / grass and the water / dirt brush to the same group and autotile mode to group and got this:

    Screen Shot 2017-05-30 at 7.14.03 PM.png

    I also tried the terrain brush however I was not quite sure what type of assets should be on in the fish looking thing (not even sure by tile set asset has that those assets), I only got this part filled in:

    Screen Shot 2017-05-30 at 7.29.06 PM.png

    Which results in:

    Screen Shot 2017-05-30 at 7.35.32 PM.png

    Thought using the brush would help me realize which tiles should go in those areas but I am even more confused after seeing this thinking that the 9 tiles I did set might not be correct. If you have an example of what tiles you use for the terrain brush or more feedback on what I could do for using the other brushes, that would be great.
     
  12. sygaki786

    sygaki786

    Joined:
    Jan 26, 2014
    Posts:
    142
    Thanks for your prompt reply. Just got back from vacation and starting to work on this again. I have a question unrelated to Super TileMap.

    I will be using Tilesheets from different assets. Unfortunately they will be having different sizes when I merge them in TexturePacker. What is the best way to resize all the images so they all split into 32*32 tiles? If one of the sprite sheets has 32*32 and the other 72*72, what is the best way to handle this so in Super Tilemap, the tiles are split evenly and in a usable manner? Also, the same sprite sheet itself may have images some of which are 32*32 and some others different.

    Would appreciate any help in this regard. This issue has been very time consuming for me since I am an Indie.

    Thanks,
    Arshad
     
  13. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    To use the bottom tiles, you need something like this:
    upload_2017-5-31_20-46-26.png

    But if you want to use the groups, you can use two groups. You are right, I tell you it wrong.
    It would be better if you could send me a test project to the email support (not here) but think this is how it should work.

    You need to make the grass to ground brush to autotile with the ground to water brush, but not the opposite.

    You can do it in many ways, for example:
    The grassToGround brush has autotiling mode other and the ground to water brush has the autotiling mode to self.
    Or you can set a ground for the grass to ground brush (ex: grassToGroundGroup) and a different group for ground to water (ex: groundToWaterGroup).
    Then set both brushes to autotile mode group, but in the group mask check the checkbox to make the first group to autotile with the second one, but not the opposite.
    upload_2017-5-31_20-57-7.png
     
  14. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Hi there,

    Right now, if you create a tileset, and you define a tile size of 32x32, all your tiles will have an aspect ration of 1:1. In case of tiles with 72x72 tiles, it will respect the ration but the resolution won't be the same.
    In the tilemap you can define the size of a cell (where the tile is rendered) so you can change the size in unity units of a tile but tiles of 72x72 will look with pixels smaller than the ones with 32x32 pixels.

    Other thing to take into account is, when you create a tileset you need to slice the atlas using the Unity sprite editor, setting the texture to multiple sprites, because if you slice the tileset using the tileset inspector view, all the tiles should be in a grid layout with the same size for all the tiles. Slicing the texture first, when you assign the texture in the atlas property field, it will ask you to use the sliced sprites instead.

    If you want to maintain the size for the tiles with a different size you can still achieve that by creating a prefab with the component TileObjectBehaviour and attaching the prefab to the tile you want to create as a separated sprite.

    If you need more help don't hesitate to ask.
     
  15. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Hey, thanks for the additional info, adding the correct Group Autotiling Masks it what I was missing, setting that properly fixes the issue.

    One unrelated bug that I did notice is that when viewing the inspector of TileSet item, scrolling does not work when the mouse is over the Group Autotiling Mask section. Just a minor bug in the editor that is even enough to work around so nothing critical but thought I should point it out anyways.

    Thanks for the help again.
     
  16. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore So I do have another question. Is there any sort of built in support for multi tile sprites? For example, the trees in this screenshot:

    Screen Shot 2017-06-02 at 6.33.18 AM.png

    I can think of some ideas that might work around being able to manage multi-tile assets through code but was just wondering if there was a built-in way to do this.
     
  17. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    You can attach a prefab with the sprite of the tree to a tile and it will paint the tree in the grid position.
     
  18. sygaki786

    sygaki786

    Joined:
    Jan 26, 2014
    Posts:
    142
    I have a set of tiles which I am using for the Ground. These tile with 32*32. However, I also have crates which are smaller in size. So I created a prefab for the crate and used that. However, they all align with the same offset so they are always in the center of the tile. If I need to place the crates next to each other, how do I do that? Do I have to create a prefab for each crate and adjust the offset differently?

    Thanks,
    Arshad
     
  19. sygaki786

    sygaki786

    Joined:
    Jan 26, 2014
    Posts:
    142
    I got it working. I created prefabs with different numbers of crates besides each other. Then painted the different prefabs.
     
  20. sygaki786

    sygaki786

    Joined:
    Jan 26, 2014
    Posts:
    142
    Once I create the ground, I would like to specify a tag for it and the layer. I only see options for Sorting Layer and Order. How do I set the Tag and the Layer for just the Ground portion of the Tilemap? Do I have to create the Ground from a Prefab and then set these properties in the Prefab?

    Thanks,
    Arshad
     
    Last edited: Jun 4, 2017
  21. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    You can change the tag and layer for the tilemap, but not for the tiles. When you chage the layer, remember to say yes to the question to change also the children gameobjects.

    If you need more help don't hesitate to ask.
     
  22. vee41

    vee41

    Joined:
    Nov 14, 2013
    Posts:
    32
    Hi,

    @CreativeSpore Interested of buying the asset, wondering few things:

    1) what are the capabilities / performance for runtime modification of tile maps? My use case is destruction of things, ie. Missile hits space ship which is (top down) tile map. Chunk of tiles would be removed/set invisible and some changed to damaged versions.

    2) can tiles hold different properties? In above case some tiles would resist damage better than other tiles and thus could be used to calculate damage missile causes more accurately.

    3) can I define concept of 'room' somehow? Room is bunch of tiles that could be defined ie. By collider covering the whole room. Can this be done via tile map prefabs?

    4) can tile maps handle lighting? Ie. lights would use colliders of wall tiles to determine how to spread. Or would it work by setting tile colors? I'm looking for something dynamic like switching lights on/off inside a room, illuminating spreading fire and so on.

    Cheers!
     
    Last edited: Jun 8, 2017
  23. ury2ok2000

    ury2ok2000

    Joined:
    Dec 29, 2012
    Posts:
    46
    Hello, can i grab the texture from the mesh? I try to pull from TilemapChunk:

    TilemapChunk.GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D;

    but this returns null. Ideally i want to create one sprite from the entire mesh/texture of the tile layer.
     
  24. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Hi there,

    I answer your questions below:

    1) what are the capabilities / performance for runtime modification of tile maps? My use case is destruction of things, ie. Missile hits space ship which is (top down) tile map. Chunk of tiles would be removed/set invisible and some changed to damaged versions.
    Modifying the tilemap in real time is really fast, event when using the special brushes and when generating the tile colliders. It's optimized to update only the modified areas, so you won't have any performance issue at all. Of course if you try to update all the tiles of a 1000x1000 tilemap you will have a performance issue, but for what you describe it should be modified in real time.

    2) can tiles hold different properties? In above case some tiles would resist damage better than other tiles and thus could be used to calculate damage missile causes more accurately.
    The tiles can hold properties, but they are the same for all the tiles of the same type.
    You can use the attached script component to a prefab and attach the prefab to a tile so a gameObject is created with a list of parameters. But I think it would be faster if you create your own component.


    3) can I define concept of 'room' somehow? Room is bunch of tiles that could be defined ie. By collider covering the whole room. Can this be done via tile map prefabs?
    In this case a room would be a TilemapGroup containing the tilemaps with all the layers. You can create a prefab of this gameObject and instantiate it later in the scene.

    4) can tile maps handle lighting? Ie. lights would use colliders of wall tiles to determine how to spread. Or would it work by setting tile colors? I'm looking for something dynamic like switching lights on/off inside a room, illuminating spreading fire and so on.
    Yes, you can handle lights if you use a material like Sprite/Diffuse in the tilemap settings.
    Also, you can use the SetTileColor methods to paint the tile vertices, and soon I will include a vertex paint tool to make it even more easy.

    If you have more question, let me know.
     

    Attached Files:

  25. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    I am not sure why it returns null, but anyway, it will return the tileset texture, not the tilemap layer image. It's the same if you access the tilemap.Tileset.AtlasTexture.
    To create an image of a tilemap, you can check how the AtlasEditorWindow works. It creates an atlas copying the tiles into a texture. It should be easy to adapt the code to create a texture of a tilemap. If you need help with this let me know.
     
  26. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore So I am trying to see if there is a brush that will allow me to get this type of effect (a.k.a. forsaken isle, rimworld, prison architect, etc.):

    Untitled.png

    The carpet brush only give me the 3x3 square and nothing else as there is no full single tile. The road brush give me everything else except that 3x3 as the 3x3 can't be fully connected like the carpet other wise the other ones don't look right. I also tried the WIP terrain brush with these assets:

    D7xYqEC.png

    but got these results:

    QmhJNhv.png

    So that does not seem to work (not sure if it is the assets I am use or something else as this brush is WIP).

    Can I get the style of brush I am looking for out of the box with this solution (maybe I am using incorrect styled assets, I am not sure) or would I have to create my own brush (in which case I am probably screwed)?
     
  27. ury2ok2000

    ury2ok2000

    Joined:
    Dec 29, 2012
    Posts:
    46
    I could definitely use some assistance. So i figured i should iterate through the tilemap, get the tile id then somehow blt this all onto a texture2d which i can then use with Sprite.Create to create my 1 sprite that is the entire tile map (i should probably say too i want to exclude any prefabs). I pieced together the below code (dont know how to tag with /code) - but dont really know what to do with the uv coord of the tile...


    for (int gy = tilemap.MinGridY; gy <= tilemap.MaxGridY; ++gy)
    {
    for (int gx = tilemap.MinGridX; gx <= tilemap.MaxGridX; ++gx)
    {
    Tile tile = tilemap.GetTile(gx, gy); // get a tile using grid coordinates, not positions
    if (tile != null) // the tile could be null, if the position is empty
    {

    uint rawTileData = tilemap.GetTileData(gx, gy);
    TileData data = new TileData(rawTileData);

    int tileId = data.tileId;

    if (tileId != 0)
    {
    Rect r = tilemap.Tileset.Tiles[tileId].uv;

    }else
    {
    //must do something for blank space, right?
    }
    }
    }
     
  28. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    I see. What you want basically is to paint a tile so that tiles is not autotiling with the neightbours, right?
    This is not possible with the current brushes unless you paint in different tilemaps. With RPG Map Editor (the other tool), you can do that by pressing shift, but internally it draws the tile in another layer.
    I was able to achieve the tile separation by painting the tiles inside the red rectangle using tiles from the palette. Maybe you could modify the terrain brush to behave differently if the shift key is pressed to create a transition.
    upload_2017-6-10_16-18-18.png
     
  29. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Well did I set up the terrain brush assets correct because the results I got with it seemed like either my assets were wrong or the terrain brush has a bug?
     
  30. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    The only thing I see wrong in your setup is in the bottom left tiles, it should be yellow all corners but one:
    upload_2017-6-10_18-10-30.png
     
  31. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    I have programmed a method to create a texture from a tilemap:
    Code (CSharp):
    1. static public Texture2D CreateTexture2DFromTilemap(Tilemap tilemap)
    2. {
    3.     int tilePxSizeX = (int)tilemap.Tileset.TilePxSize.x;
    4.     int tilePxSizeY = (int)tilemap.Tileset.TilePxSize.y;
    5.     Texture2D output = new Texture2D(tilemap.GridWidth * tilePxSizeX, tilemap.GridHeight * tilePxSizeY, TextureFormat.ARGB32, false);
    6.     output.filterMode = FilterMode.Point;
    7.     output.SetPixels32(new Color32[output.width * output.height]);
    8.     output.Apply();          
    9.     Texture2D atlasTexture = tilemap.Tileset.AtlasTexture;
    10.     System.Action<Tilemap, int, int, uint> action = (Tilemap source, int gridX, int gridY, uint tileData) =>
    11.     {
    12.         gridX -= source.MinGridX;
    13.         gridY -= source.MinGridY;
    14.         Tile tile = tilemap.Tileset.GetTile(Tileset.GetTileIdFromTileData(tileData));
    15.         if(tile != null)
    16.         {
    17.             Color[] srcTileColors = atlasTexture.GetPixels(Mathf.RoundToInt(tile.uv.x * atlasTexture.width), Mathf.RoundToInt(tile.uv.y * atlasTexture.height), tilePxSizeX, tilePxSizeY);
    18.             output.SetPixels(gridX * tilePxSizeX, gridY * tilePxSizeY, tilePxSizeX, tilePxSizeY, srcTileColors);
    19.         }
    20.     };
    21.     IterateTilemapWithAction(tilemap, action);
    22.     output.Apply();
    23.     return output;
    24. }
    25.  
    You need to make the atlas texture readable, not readable by default.
    I have added this code in the TilemapEditor.cs class:
    Code (CSharp):
    1. if(GUILayout.Button("Export To Png"))
    2. {
    3.     string path = EditorUtility.SaveFilePanel("Save tilemap Png", AssetDatabase.GetAssetPath(m_tilemap), m_tilemap.name + ".png", "png");
    4.     if(!string.IsNullOrEmpty(path))
    5.     {
    6.         AtlasEditorWindow.MakeTextureReadable(m_tilemap.Tileset.AtlasTexture);
    7.         Texture2D tilemapText = TilemapUtils.CreateTexture2DFromTilemap(m_tilemap);
    8.         System.IO.File.WriteAllBytes(path, tilemapText.EncodeToPNG());
    9.     }
    10. }
    11.  
    If you place it in the right place, it will add a button in the tilemap inspector to export the tilemap to a png file:
    upload_2017-6-10_18-13-5.png

    I have attached the new TIlemapUtils.cs file with the extra method to export a tilemap to a texture2D.
     

    Attached Files:

  32. vee41

    vee41

    Joined:
    Nov 14, 2013
    Posts:
    32
    Thanks, bought. Everything seems to work as you described and overall really impressed on how well it works!

    One additional question :
    What would be easiest way to select tiles that overlap object? I'd like to map initial direction of explosion to make it spread more realisticly. Thought this could be done by creating 'explosion shape' object, any tiles intersecting that would be preferred for spreading the explosion.
    Other option would be to have an angle from impact point of explosion and highlight tiles caught between the two vectors.

    So the question is which you see the most efficient way to use API to achieve these?
     
  33. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Well changing the terrain tiles as you specified did fix that brush to work better but it was still not what I am looking for.

    Not 100% sure I know what you mean but while I don't want the tiles around the tiles that are painted with the brush to be autotiled, I do need to know if the tiles around the current brushed tile has other tiles that are using the same brush if that makes sense. I am also looking for a squared based brush as conceptually that is easier for me to grasp right now.

    Let me try to illustrate what I am looking for a little better. The following examples are using this tileset:

    Screen Shot 2017-06-11 at 10.20.39 PM.png

    Lets say I have a 3x3 square of tile of (O means it is a brush based tile):

    OXO
    XOX
    OXO

    That since none of the brushed tiles have another brushed tile on a direct side, that would be render like:

    Screen Shot 2017-06-11 at 10.32.20 PM.png

    Now lets change that 3X3 to:

    OOO
    XOX
    OXO

    Now that there is a direct connection, all the of 4 brush tiles that are connection at the top would be changed to look like this:

    Screen Shot 2017-06-11 at 10.37.59 PM.png

    With the tileset above I am above to make from my basic testing all the following shapes:

    Screen Shot 2017-06-11 at 10.44.56 PM.png

    I still would need to do more testing to see if the assets I have would be everything I need (and I could probably use rotation / flipping to remove a few of those assets) to create any shaped needed but hopefully those examples I gave makes clear as to what I am trying to achieve with this tool.

    A few other things to mention is that the map is user modify-able within the game, needs to be able to be generated dynamically, and most if not all landscape tiles will need this functionality (which some / all seems like it would be a lot harder to do I need to manage multiple map layers).

    So I have 2 questions:

    1. With this more detailed information, am I still going to have to deal with multiple maps to get the effect I am looking for or would I be able to create a brush to do what I am looking for (I would hope I could as it seems to the naive eye that I am trying to do something very similar to the carpet / road brushes)?

    2. Do you have any detailed brush tutorials or heavily commented brushes that might help me understand how to create a brush that I am looking to create (I tried to look at the road brush but can't really understand how that code is working)?
     
    Last edited: Jun 12, 2017
  34. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Well, you can use the methods in the class TilemapUtils to get the tile grid position from a world position.
    Also, for SetTileData and GetTileData to set and get a tile in the tilemap, you have two versions, one using grid positions and another using world position.

    To draw a line, you can use the TilemapDrawingUtils class. It has a lot of methods to draw shapes like lines, rectangles, circles, ellipses (filled and only the outline).
    For example, to draw a line from positionA to positionB using the tile id 8, you can use:
    Code (CSharp):
    1. TilemapDrawingUtils.DrawLine(tilemap, posA, posB, new uint[,] { {8} });
    2. tilemap.UpdateMesh(); //Remember to call this to update the mesh when all changes has been made to improve the performance
    The uint[,] parameter could be estrange, but it allow you to use a patter of tiles instead of just one.
    Here you can see all the drawing tools and patterns explained.
     
  35. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    What I meant was the red tile is not contemplated in the terrain brush neither in the carpet brush. It looks the neighbours to get the tile id, and in this case, it has a neighbor in both sides, so it would choose the full ground tile.
    I guess what you want is, if your draw the left and right tile, there will be a tile in the middle with the center using the background color (grass), but in the way the tilemap works it would be tricky to achieve. There are some cases where a tile would affect a tile that affects another tiles, etc.
    To make terrain tiles properly, it would be needed to implement an special terrain editor with terrain ids like Tiled. In a future release it could be possible to add this editor, but it won't be soon.

    About the tutorial to create brushes, it is explained in the code, in the interface used to implement the brushes IBrush.
    For example, the RoadBrush.
    You have to implement the Refresh Method. This method is called when a tilemap is updated and you need to return the tile id checking the neighbours.
    upload_2017-6-12_20-41-55.png

    It is a little complex because there are some special cases like using a random brush to paint a tile from a road brush and when using animated tiles in non-animates brushes. But taking one of the brushes as template it should be easy to create your own brush. If you have questions in the process don't hesitate to ask.
     
  36. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Well I am slowly making some progress (probably in a hacky way but I will worry about that when I get something that actually functions) however I am running into an issue with the inspector for the brush. The issue seems to be that if the brush gets to the point where their is a scrollbar, the tile selection stuff gets messed up:

    Screen Shot 2017-06-12 at 10.58.06 PM.png

    Because of the way I am going to want to build this brush, it will have a lot of different variations in tiles so having the inspector be scrolling is something that in all likely is going to be required but since I know nothing about editor scripting, I could not figure out what was causing this or hoe to fix it in either BrushTileGridControl or TileGridControl.

    I will also mention that the built-in brushes have the same issue if I shrink the inspectors height enough.

    Any help with fixing the inspector in this case would be great.
     
  37. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Any update on the inspector issue?

    Also I was able to create my brush at least as far as I can tell in my testing so far:

    Screen Shot 2017-06-14 at 5.55.24 AM.png

    I had to remove the brush inspector element in order to work past the inspector issue.

    Screen Shot 2017-06-14 at 5.55.51 AM.png

    A couple of questions about brushes I have are:

    1. So because of how this brush works, I have 47 different tiles (a lot less actual sprites, just using the flip / rotate checkboxes for a lot of the tiles) and the most sane way I could figure to write the Refresh() method was:

    Code (CSharp):
    1. if (!north && !east && !south && !west) {
    2.     temp = TileIds[0];
    3. } else if (north && !east && south && !west) {
    4.     temp = TileIds[5];
    5. } else if (!north && east && !south && west) {
    6.     temp = TileIds[10];
    7. } else if (/*!northWest && */north && /*!northEast && */!east && /*!southEast && */!south && /*!southWest && */!west) {
    8.     temp = TileIds[1];
    9. } else if (/*!northWest && */!north && /*!northEast && */east && /*!southEast && */!south && /*!southWest && */!west) {
    10.     temp = TileIds[2];
    11. } else if (/*!northWest && */north && northEast && east && /*!southEast && */!south && /*!southWest && */!west) {
    12.     temp = TileIds[3];
    13. } else if (/*!northWest && */!north && /*!northEast && */!east && /*!southEast && */south && /*!southWest && */!west) {
    14.     temp = TileIds[4];
    15. }/* else if (!northWest && north && !northEast && !east && !southEast && south && !southWest && !west) {
    16. //                temp = TileIds[5];
    17. }*/ else if (/*!northWest && */!north && /*!northEast && */east && southEast && south && /*!southWest && */!west) {
    18.     temp = TileIds[6];
    19. } else if (/*!northWest && */north && northEast && east && southEast && south && /*!southWest && */!west) {
    20.     temp = TileIds[7];
    21. } else if (/*!northWest && */!north && /*!northEast && */!east && /*!southEast && */!south && /*!southWest && */west) {
    22.     temp = TileIds[8];
    23. } else if (northWest && north && /*!northEast && */!east && /*!southEast && */!south && /*!southWest && */west) {
    24.     temp = TileIds[9];
    25. }/* else if (!northWest && !north && !northEast && east && !southEast && !south && !southWest && west) {
    26. //                temp = TileIds[10];
    27. }*/ else if (northWest && north && northEast && east && /*!southEast && */!south && /*!southWest && */west) {
    28.     temp = TileIds[11];
    29. } else if (/*!northWest && */!north && /*!northEast && */!east && /*!southEast && */south && southWest && west) {
    30.     temp = TileIds[12];
    31. } else if (northWest && north && /*!northEast && */!east && /*!southEast && */south && southWest && west) {
    32.     temp = TileIds[13];
    33. } else if (/*!northWest && */!north && /*!northEast && */east && southEast && south && southWest && west) {
    34.     temp = TileIds[14];
    35. } else if (northWest && north && northEast && east && southEast && south && southWest && west) {
    36.     temp = TileIds[15];
    37. } else if (/*!northWest && */!north && /*!northEast && */east && !southEast && south && /*!southWest && */!west) {
    38.     temp = TestIds[0];
    39. } else if (/*!northWest && */!north && /*!northEast && */east && !southEast && south && !southWest && west) {
    40.     temp = TestIds[1];
    41. } else if (/*!northWest && */!north && /*!northEast && */!east && /*!southEast && */south && !southWest && west) {
    42.     temp = TestIds[2];
    43. } else if (/*!northWest && */north && !northEast && east && !southEast && south && /*!southWest && */!west) {
    44.     temp = TestIds[3];
    45. } else if (!northWest && north && !northEast && east && !southEast && south && !southWest && west) {
    46.     temp = TestIds[4];
    47. } else if (!northWest && north && /*!northEast && */!east && /*!southEast && */south && !southWest && west) {
    48.     temp = TestIds[5];
    49. } else if (/*!northWest && */north && !northEast && east && /*!southEast && */!south && /*!southWest && */!west) {
    50.     temp = TestIds[6];
    51. } else if (!northWest && north && !northEast && east && /*!southEast && */!south && /*!southWest && */west) {
    52.     temp = TestIds[7];
    53. } else if (!northWest && north && /*!northEast && */!east && /*!southEast && */!south && /*!southWest && */west) {
    54.     temp = TestIds[8];
    55. } else if (northWest && north && !northEast && east && !southEast && south && !southWest && west) {
    56.     temp = Test2Ids[0];
    57. } else if (!northWest && north && northEast && east && !southEast && south && !southWest && west) {
    58.     temp = Test2Ids[1];
    59. } else if (!northWest && north && !northEast && east && !southEast && south && southWest && west) {
    60.     temp = Test2Ids[2];
    61. } else if (!northWest && north && !northEast && east && southEast && south && !southWest && west) {
    62.     temp = Test2Ids[3];
    63. } else if (!northWest && north && northEast && east && southEast && south && southWest && west) {
    64.     temp = Test3Ids[0];
    65. } else if (northWest && north && !northEast && east && southEast && south && southWest && west) {
    66.     temp = Test3Ids[1];
    67. } else if (northWest && north && northEast && east && southEast && south && !southWest && west) {
    68.     temp = Test3Ids[2];
    69. } else if (northWest && north && northEast && east && !southEast && south && southWest && west) {
    70.     temp = Test3Ids[3];
    71. } else if (!northWest && north && northEast && east && southEast && south && !southWest && west) {
    72.     temp = Test4Ids[0];
    73. } else if (!northWest && north && !northEast && east && southEast && south && southWest && west) {
    74.     temp = Test4Ids[1];
    75. } else if (northWest && north && !northEast && east && !southEast && south && southWest && west) {
    76.     temp = Test4Ids[2];
    77. } else if (northWest && north && northEast && east && !southEast && south && !southWest && west) {
    78.     temp = Test4Ids[3];
    79. } else if (/*!northWest && */!north && /*!northEast && */east && !southEast && south && southWest && west) {
    80.     temp = Test5Ids[0];
    81. } else if (/*!northWest && */!north && /*!northEast && */east && southEast && south && !southWest && west) {
    82.     temp = Test5Ids[1];
    83. } else if (northWest && north && !northEast && east && /*!southEast && */!south && /*!southWest && */west) {
    84.     temp = Test5Ids[2];
    85. } else if (!northWest && north && northEast && east && /*!southEast && */!south && /*!southWest && */west) {
    86.     temp = Test5Ids[3];
    87. } else if (northWest && north && !northEast && east && southEast && south && !southWest && west) {
    88.     temp = Test6Ids[0];
    89. } else if (!northWest && north && northEast && east && !southEast && south && southWest && west) {
    90.     temp = Test6Ids[1];
    91. } else if (/*!northWest && */north && northEast && east && !southEast && south && /*!southWest && */!west) {
    92.     temp = Test7Ids[0];
    93. } else if (northWest && north && /*!northEast && */!east && /*!southEast && */south && !southWest && west) {
    94.     temp = Test7Ids[1];
    95. } else if (/*!northWest && */north && !northEast && east && southEast && south && /*!southWest && */!west) {
    96.     temp = Test7Ids[2];
    97. } else if (!northWest && north && /*!northEast && */!east && /*!southEast && */south && southWest && west) {
    98.     temp = Test7Ids[3];
    99. }
    I know you seem to use bitshifting of something like that for the road tile however not even sure if that is possible with this many tiles and even if it was, it would be really hard to maintain / understand when reading it (at least for me). I assume performance wise this should be ok as I assume refresh is only when the map is changes and the map will only be change mostly change 4-5 tiles at most at a time (and when generating the map, there will be a loading screen). Anything I should be concerned with writing the code like this?

    2. What is the GetSubtitle() method use for as I did not modify that but everything in my limited testing still works so trying to figure out what that method should be doing?
     
  38. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    I think it should be ok. Today, the processors are really fast and I don't think you notice a big impact in the performance.

    The GetSubtile method is used to support using animated brushes as a tile of the brush.

    By the way, when you said you needed 47 tiles I remembered this.
    https://gamedevelopment.tutsplus.co...ng-to-auto-tile-your-level-layouts--cms-25673

    Thanks to another customer, Nikola Kasabov, I will add this brush in the next version. I still need to check it before release it, but could be what you are looking for.
     
  39. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore Well even though I have created a brush that seems to work for my needs, if you need a tester for your version, I'd be happy to test it, I am sure your version will be better than whatever I come up with.
     
  40. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Sure! You can send me a private message with your email and I will send you a test version as soon as I have finished it.
     
  41. Rabagast

    Rabagast

    Joined:
    Jan 30, 2013
    Posts:
    78
    Hi!
    I try to import TMX-file into Unity, but I get this error.

    NullReferenceException: Object reference not set to an instance of an object
    CreativeSpore.TiledImporter.TmxMap.FixExportedTilesets (System.String relativePath) (at Assets/CreativeSpore/SuperTilemapEditor/Scripts/TiledImporter/Editor/TmxMap.cs:56)
    CreativeSpore.TiledImporter.TmxTilemap.LoadFromFile (System.String sFilePath) (at Assets/CreativeSpore/SuperTilemapEditor/Scripts/TiledImporter/Editor/TmxTilemap.cs:102)
    CreativeSpore.TiledImporter.TmxImporter.CreateTilesetFromTmx () (at Assets/CreativeSpore/SuperTilemapEditor/Scripts/TiledImporter/Editor/TmxImporter.cs:28)


    I do the same as in the tutorial. Is it a bug? Or is it something I do wrong?

    When I tried to import desert.tmx which came with SuperTileMapEditor, I got this error:

    Assertion failed on expression: '!(o->TestHideFlag(Object::kDontSaveInEditor) && (options & kAllowDontSaveObjectsToBePersistent) == 0)'
    UnityEditor.AssetDatabase:CreateAsset(Object, String)
    CreativeSpore.TiledImporter.TmxImporter:CreateTilesetFromTmx(String, String) (at Assets/CreativeSpore/SuperTilemapEditor/Scripts/TiledImporter/Editor/TmxImporter.cs:65)
    CreativeSpore.TiledImporter.TmxImporter:CreateTilesetFromTmx() (at Assets/CreativeSpore/SuperTilemapEditor/Scripts/TiledImporter/Editor/TmxImporter.cs:35)


    I use version 1.4.3.4
     
  42. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    It should work with the deser.tmx file so I guess it's probably a Unity bug.
    Did you try to import the tool in a new project? What version of Unity are you using?
    I have tested it with version 5.6.1f1 and it works.
     
  43. Rabagast

    Rabagast

    Joined:
    Jan 30, 2013
    Posts:
    78
    I have Unity 5.6.1f1. I didn't try it in a new project. I will try.
     
  44. MrJBRPG

    MrJBRPG

    Joined:
    Nov 22, 2015
    Posts:
    40
    I was half-thinking between getting this and SpriteTile, and I decided to purchase this one because the guys managed to demonstrate the procedural generation as well as having very robust tile editing features. I have quite a few questions in regards to procedural generation and chunks as well as more detailed takes beyond 9x9 tile stuff:

    1: Since it is possible to do procedural generation on individual tiles, can the same be said for generating chunks of tiles, even creating predefined chunks randomly along the way? I also wonder how with some general suggestions.

    2. I wonder if it is possible to create a grid of sprites that is longer than 9x9. If so, then how can that be done like a 16 x 16 or 25 x 25 for bigger tiles like racing / top-down driving games?



    P.S. Edit:
    Oh... Found a small thing on page 3, but I would be happy to have general answers out of curiosity.
     
  45. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Hi there! Good to know you finally decided to use this tool ;)
    About your questions:

    1: Since it is possible to do procedural generation on individual tiles, can the same be said for generating chunks of tiles, even creating predefined chunks randomly along the way? I also wonder how with some general suggestions.
    I have two choices here. You can create rooms (using a tilemap group to manage the layers(tilemaps)) and create a prefab so later you can instantiate the prefabs to build the level.
    Or you create the levels on the fly or even copy the tiles in a room in a big tilemap so you don't need instantiate the prefab and only use it as a template.


    2. I wonder if it is possible to create a grid of sprites that is longer than 9x9. If so, then how can that be done like a 16 x 16 or 25 x 25 for bigger tiles like racing / top-down driving games?
    I am not sure what you mean about having a grid of sprites longer than 9x9. Do you mean using the brushes like the carpet brush or road brush? I don't see where you found a limitation in the number of tiles a tilemap can hold. Could you reformulate this question?
     
  46. Nixaan

    Nixaan

    Joined:
    May 30, 2013
    Posts:
    118
    Is it possible to somehow change brush id? I need that because I'm trying to swap the tileset of a tilemap. It swaps correctly but if the tilemap is edited after the change then auto-tiling gets corrupted because the brush IDs of the two tilesets are not identical.
     
  47. ryanzec

    ryanzec

    Joined:
    Jun 10, 2008
    Posts:
    696
    @CreativeSpore So I was wondering if you would have any recommendations on how to go about creating a map to that fully editable / destructible by the user in game. I need to be able to allow the user to use tools on the terrain to be able to dig it up (water, grass, sand, mountains, etc.). The max map size is going to be about 300,000 tiles so using a prefab with a 2d collider and script for destruction functionality does not work (takes a few minutes to generate map and performance is bad as I expected with that many colliders). Not sure if there are any recommended way to going about this problem before I try to come up with a custom solution which right now is probably going to be me creating a mutli-dimensional array that stores the data for the tile (what tile it is, if it can be modified, if something can be placed, what tool is needed to collect / dig up, etc.) and then use the mouse position to determine tile to be modified when the user uses the left button with an active tool equipped.
     
  48. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Yes, you can change the brushId by code, accessing the brush list and changing the id, but be careful not to replicate the same id for two different brushes:
    tileset.Brushes[idx].id = newId;

    Also, you can change it in the editor if you activate the debug mode:
    upload_2017-6-23_18-32-59.png

    upload_2017-6-23_18-33-33.png
     

    Attached Files:

  49. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    For big maps I recommend you to use some kind of procedural generation and update only the areas around the camera.
    If you check the forum, I posted an script about generating the tilemap on the fly around the camera.
    I have attached the package in this post.
     

    Attached Files:

  50. CreativeSpore

    CreativeSpore

    Joined:
    Nov 6, 2014
    Posts:
    1,192
    Important Notice about Unity version 5.6.2f1!
    This version has a bug when setting the points of a PolygonCollider2D. It means, if you are using PolygonColliders for your tilemaps you will see an assertion error message.
    To fix it you need to change this line to use SetPath instead:
    upload_2017-6-23_18-40-56.png

    This will be fixed in the next version.