Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Populate tilemap-palette with custom TileBase class?

Discussion in '2D Experimental Preview' started by Kirsche, Aug 29, 2018.

  1. Kirsche

    Kirsche

    Joined:
    Apr 14, 2015
    Posts:
    121
    If you drag a sprite atlas onto the tilemap-palette Unity automatically generates the required tile-assets. However I'd like Unity to use my custom TileBase-inherited class for all tiles, so I can add a few useful properties like SurfaceType.

    Is there anyway to tell Unity to use my custom tile class?
     
  2. BlackHoleTracer

    BlackHoleTracer

    Joined:
    Jan 23, 2014
    Posts:
    7
    Yes, write your class (inherited from TileBase or Tile) and add to code of this class such lines:

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. // The following is a helper that adds a menu item to create a MyTile Asset
    3.     [MenuItem("Assets/Create/MyTile")]
    4.     public static void CreateMyTile()
    5.     {
    6.         string path = EditorUtility.SaveFilePanelInProject("Save My Tile", "New My Tile", "Asset", "Save My Tile", "Assets");
    7.         if (path == "")
    8.             return;
    9.     AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<MyTile>(), path);
    10.     }
    11. #endif
    These lines will create new menu item (in Unity Editor) here: Assets->Create->MyTile. Click this and you will get your Tile.

    See Unity example here: https://docs.unity3d.com/Manual/Tilemap-ScriptableTiles-Example.html
    And you can use shorter alternative - CreateAssetMenuAttribute ( https://docs.unity3d.com/ScriptReference/CreateAssetMenuAttribute.html )
     
  3. tgaldi

    tgaldi

    Joined:
    Oct 28, 2015
    Posts:
    102
    Is there a better solution for this? It seems cumbersome to have to create a new Tile object each time you want to add properties to a new sprite you want to make into a tile, as well as individually drag those new objects into the tile palette.

    Let's say I create a WallTile that has a property that says this tile is impassable. Every time I have a new sprite that represents a wall I would have to create another WallTile scriptable object, add the sprite asset to it, then drag it into the correct tile palette.

    Is there a way to customize the tile palette inspector to assign tile types to tiles already added to the palette?
     
    Last edited: Feb 6, 2019
  4. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Unfortunately, this is not possible now. We will improve the Tile Palette to have this functionality.
     
    P10tr3k and tgaldi like this.
  5. P10tr3k

    P10tr3k

    Joined:
    Sep 29, 2016
    Posts:
    7
    I'm also looking for that. It would be very nice feature :)
     
  6. TestLearnRepeat

    TestLearnRepeat

    Joined:
    Oct 28, 2019
    Posts:
    3
    Has this been improved in the 3 years since?
     
  7. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    In 2019.2, with the Tilemap Editor package, you can use the
    CreateTileFromPalette
    attribute to specify a method to create the Tile that you want when dragging and dropping onto the Palette. If you have more than one such method declared, you can choose the one you want from Preferences -> Tile Palette -> Tile Palette Create Tile Method.

    An example:

    Code (CSharp):
    1.  
    2. using UnityEditor.Tilemaps;
    3. using UnityEngine;
    4. using UnityEngine.Tilemaps;
    5.  
    6. public class BlueTile : Tile
    7. {
    8.     public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
    9.     {
    10.         base.GetTileData(position, tilemap, ref tileData);
    11.         tileData.color = Color.blue;
    12.     }
    13.  
    14.     [CreateTileFromPalette]
    15.     public static TileBase CreateBlueTile(Sprite sprite)
    16.     {
    17.         var blueTile = ScriptableObject.CreateInstance<BlueTile>();
    18.         blueTile.sprite = sprite;
    19.         blueTile.name = sprite.name;
    20.         return blueTile;
    21.     }
    22. }
    23.  
    24.  
     
    reiniat, kojikyo256 and Grizmu like this.
  8. The_Arrival

    The_Arrival

    Joined:
    Dec 3, 2014
    Posts:
    82
    Thanks for your answer ChuanXin. Though this Override helps a LOT, it´s still a bit tedious process to make it this way.

    Whenever i update my TileClass with the next feature which gets configured/setup at creationTime, i need to dump an recreate all Pallets. Is there an easy way to re-create them using the same sprites?
     
    Last edited: Dec 13, 2019
  9. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Could you explain more about this? Do you mean that you want the update the Tiles already set in a Tile Palette to a different Scriptable Tile class?
     
  10. The_Arrival

    The_Arrival

    Joined:
    Dec 3, 2014
    Posts:
    82
    No, i´m talking about the same class, but while you develop your game, one might constantly working on that class, giving it new features and abilities. Some of them should/might be configured during creation time. For example i´ve a certain name convention for my hex-tile sprites, which then translates in a certain enum configuration. All of this is done during creation time, so i can check the tile-assets in the editor.


    Code (CSharp):
    1. [CreateTileFromPalette]
    2.     public static TileBase CreateTileClass(Sprite sprite)
    3.     {
    4.         var tClass = ScriptableObject.CreateInstance<TileClass>();
    5.         tClass.sprite = sprite;
    6.         tClass.name = sprite.name;
    7.         tClass.Setup(Vector3Int.zero);
    8.         return tClass;
    9.     }
    10.    
    11.     public void Setup(Vector3Int pos) {
    12.         biome = TileUtils.GetBiomeForTileAsset(name);
    13.         type = TileUtils.GetTypeForTileAsset(name);
    14.         level = TileUtils.GetLevelForTileAsset(name);
    15.         this.pos = pos;
    16.     }
    Later on i´m planing to setup even more details about that tile during creation time... for that case a "Recreate all tiles" button in the palette would be great
     
  11. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    We will add this to our backlog and check this out, thanks!
     
    CheekySparrow78 likes this.
  12. UselessGameDev

    UselessGameDev

    Joined:
    Jul 15, 2018
    Posts:
    3
    Hi, sorry to bump this up but this is the first search engine result and I found a solution that's somewhat janky but works rather well and takes like 5s to setup with no editor code.

    You have your custom tile class, inherited from
    TileBase
    or
    Tile
    . Let's call it
    FloraTile
    because that's what I use.

    Select the tile asset (that you created by dragging your sprite onto the tile palette).
    Switch the inspector to Debug mode. Notice that by default the asset uses the
    Tile
    script.

    upload_2021-12-8_10-44-2.png upload_2021-12-8_10-44-12.png

    Hotswap the
    Tile
    script of the asset with your custom script.

    upload_2021-12-8_10-44-33.png

    You're done.

    Pros:
    - You can still use the handy bulk-creation method of dragging your atlas onto the tile palette
    - You can bulk edit the tiles to change the script

    Cons: None so far,
    GetTile<FloraTile>(position)
    works fine by me and I can access my custom extra data.

    Let me know if this works for you
    Cheers
    Leonard
     
  13. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    I'm using 2023.1.0 and tiles have a 'GameObject to Instanciate' property which I assumed could be usedto link a GO to a tile TYPE. You can drag a prefab in there, but that means all instances of that tile will have the same properties and property values, not ideal.

    the other method, overriding Tile will allow you to add a property or field, but it will have to be the same property and property value as well for every instance of that tile on the map.

    Clicking on a custom tile when it's placed in the map does not show the extra property in the inspector

    Associating data with map tiles is something we've had since the 1980's in map editors, it's shocking maps have been out for years now in Unity and still don't have this basic functionality.
     
    Last edited: Apr 4, 2023