Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Editing tilemaps in real time.

Discussion in '2D' started by Morgomir, Mar 31, 2019.

  1. Morgomir

    Morgomir

    Joined:
    Aug 17, 2018
    Posts:
    9
    Hi guys ! I'm currently testing things about tilemaps and I meet a big issue. I'm trying to generate and edit tilemaps in real time and I achieved that but with only one palette. I can't figure out how to properly do it with multiple tilesets.

    Here is my goal, I have a class that contains a tilemap and multiple tilesets (groups of 15 tiles, to display them in a beautiful way ;) ). This class can edit the tilemap in such a way it adds the tiles from the tilesets, choosing the right tile from the 15 available depending on the neighbours and rotating them. When it adds a tile, it also refreshes the tiles around it to display them correctly (cf screenshot).

    Screenshot_1.png


    The problem is that when it refreshes the tiles, there is no way to know where the tile which needs to be refreshed comes from. It can't know from what tileset it comes from.

    I've tried a few things like adding a single/double entry List to remember the "ID" of the tiles but, the tilemap being negative and positive on both axis, it brings more bad than good.

    I've been thinking of making a new class, child of Tile with a "public int ID" added, so I could really easily find what is the tile but doing so doesn't allow me to edit those "AdvancedTiles" in Unity anymore.

    I'm kind of stuck here. I think I can find a solution but that will be very ugly to look at and I'm trying to do things properly so maybe you guys got a better idea ? Maybe should I learn to edit the inspector to use those AdvancedTiles ?
    It seems to me that making childs of Objects like Tiles must be very useful (maybe even essential) to do more complex things with it. I'm refering to you, what do you think ?

    Thanks in advance, here is a bit of code that could help you understand what my problem is :

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Tilemaps;
    3.  
    4. public class scr_Tilemap : MonoBehaviour
    5. {
    6.     [System.Serializable]
    7.     public class TileSet
    8.     {
    9.         public Tile[] index;
    10.     }
    11.  
    12.     private Tilemap tilemap;
    13.    
    14.     public TileSet[] tileSets;
    15.     public Camera mainCamera;
    16.  
    17. ...
    18. ...
    19. ...
    20.  
    21.  
    22.     // Set a single Tile and refreshes the tiles around it
    23.     public void SetTile(Vector3Int position, int tileID, bool add)
    24.     {
    25.         AddTile(position, tileID, add);
    26.        
    27.         // Refresh around the tile
    28.         for (int i = -1; i < 2; i++)
    29.             for (int j = -1; j < 2; j++)
    30.                 RefreshTile(position + new Vector3Int(i, j, 0), tileID);
    31.     }
    32.  
    33.     // Add a Tile, use directly for generating, not for editing
    34.     public void AddTile(Vector3Int position, int tileID, bool add)
    35.     {
    36.         tilemap.SetTile(position, null);
    37.         if (!add)
    38.             return;
    39.         tilemap.SetTile(position, tileSets[tileID].index[14]);
    40.     }
    41.  
    42.     // Refreshes a Tile depending on the neighbours around it
    43.     public void RefreshTile(Vector3Int position, int tileSetIndex)
    44.     {
    45.         if (tilemap.GetTile(position) == null)
    46.             return;
    47.  
    48.         bool[] neighbours = { false, false, false, false, false, false, false, false };
    49.         int[] index_and_rotation = { 0, 0 };
    50.  
    51.         // Just get the neighbours
    52.         if (tilemap.GetTile(position + new Vector3Int(-1, 1, 0)) != null)
    53.             neighbours[0] = true;
    54.         if (tilemap.GetTile(position + new Vector3Int(0, 1, 0)) != null)
    55.             neighbours[1] = true;
    56.         if (tilemap.GetTile(position + new Vector3Int(1, 1, 0)) != null)
    57.             neighbours[2] = true;
    58.         if (tilemap.GetTile(position + new Vector3Int(1, 0, 0)) != null)
    59.             neighbours[3] = true;
    60.         if (tilemap.GetTile(position + new Vector3Int(1, -1, 0)) != null)
    61.             neighbours[4] = true;
    62.         if (tilemap.GetTile(position + new Vector3Int(0, -1, 0)) != null)
    63.             neighbours[5] = true;
    64.         if (tilemap.GetTile(position + new Vector3Int(-1, -1, 0)) != null)
    65.             neighbours[6] = true;
    66.         if (tilemap.GetTile(position + new Vector3Int(-1, 0, 0)) != null)
    67.             neighbours[7] = true;
    68.  
    69.         // Return the index and rotation to chose in the tileset, the function is not really interesting to look at for this problem.
    70.         index_and_rotation = TilesBehaviour.What_tile(neighbours);
    71.  
    72.         // Here is the problem, instead of using tileSetIndex, I should find what is the ID of the tile and use it
    73.         Tile tileToAdd = tileSets[tileSetIndex].index[index_and_rotation[0]];
    74.         tileToAdd.transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, (index_and_rotation[1] * 90)), Vector3.one);
    75.         tilemap.SetTile(position, null);
    76.         tilemap.SetTile(position, tileToAdd);
    77.     }
    78. }
    I'm here if you need more info :)
    Thanks
     
  2. Morgomir

    Morgomir

    Joined:
    Aug 17, 2018
    Posts:
    9
  3. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, we have some implemented scripts of what I think you are trying to do at:

    https://github.com/Unity-Technologies/2d-extras/blob/master/Assets/Tilemap/Tiles/Terrain Tile/Scripts/TerrainTile.cs
    https://github.com/Unity-Technologies/2d-extras/blob/master/Assets/Tilemap/Tiles/Rule Tile/Scripts/RuleTile.cs

    There is an example Unity project at:
    https://github.com/Unity-Technologies/2d-techdemos
    where you could try painting with the Tiles in the Terrain Tiles palette, or with some of the Tiles in the Rule Tiles palette.
     
  4. Morgomir

    Morgomir

    Joined:
    Aug 17, 2018
    Posts:
    9
    Hi, thanks a lot ! I'm gonna check that.
    I already found a few things that interest me a lot, I'll come back to this post with my discoveries.