Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

How do I place a Tile from a Tile Palette by script?

Discussion in '2D' started by Unity_Ghost13, Apr 25, 2019.

Thread Status:
Not open for further replies.
  1. Unity_Ghost13

    Unity_Ghost13

    Joined:
    Jan 26, 2019
    Posts:
    8
    I’m doing a TileVania style game. I'm making the traps system and I need to place some Tiles by script as part of my traps systems. I didn't found nothing in Docs.
     
  2. beanie4now

    beanie4now

    Joined:
    Apr 22, 2018
    Posts:
    311
  3. Jamesjxiao123

    Jamesjxiao123

    Joined:
    Jul 9, 2019
    Posts:
    2
    i have this problem too, i want to create a palette with a range sprites, so have you find the right answer?
     
  4. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    558
    You can also use a "brush" to do it, that way if you have custom behavior for the brush, all rules are respected.

    Example:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using Tiles;
    3. using UnityEngine;
    4. using UnityEditor.Tilemaps;
    5. using UnityEngine.Tilemaps;
    6.  
    7. /* The purpose of this script is to determine if it is possible to paint onto a tilemap
    8. * during runtime. (it is!)
    9. *
    10. */
    11.  
    12. namespace Test
    13. {
    14.     public class TestPaint : MonoBehaviour
    15.     {
    16.         public TileBase tileAsset;
    17.         public Tilemap tilemap;
    18.  
    19.         public Grid grid;
    20.         // Use this for initialization
    21.  
    22.         void Start () {
    23.             AdvancedTileBrush brushInstance = ScriptableObject.CreateInstance<AdvancedTileBrush>();
    24.  
    25.             Vector4 v = new Vector4(1f, 0, 0, 0);
    26.             Vector4 v2 = new Vector4(0, 1f, 0, 0);
    27.             Vector4 v3 = new Vector4(0, 0, 1f, 0);
    28.             Vector4 v4 = new Vector4(0, 0, 0, 1f);
    29.  
    30.             brushInstance.cells[0] = new GridBrush.BrushCell{tile = tileAsset, color = Color.white, matrix = new Matrix4x4(v,v2,v3,v4)};
    31.             for (int i = 0; i < 10; i++)
    32.             {
    33.                 brushInstance.Paint(grid, tilemap.gameObject ,new Vector3Int(i,i,0));
    34.             }
    35.         }
    36.     }
    37. }
     
  5. hlw

    hlw

    Joined:
    Aug 12, 2017
    Posts:
    250
    My advice for adding tiles by script during runtime:
    Create a new struct that contains a public Tile (tile) and a public String (name). Make that struct and its field serializables.

    Create a new C# script deriving from ScriptableObject, with a [CreateAssetMenu] thing (unity tutorial about scriptableObjects include the way to do so), that contains a List<yourNewStruct>, make it serializable.
    Right clic somewhere in your asset folder and create a new "Whatever the name you gave to your scriptableObject in the createassetmenu thing in your script'.
    Add the tiles you might want to use into the list of that newly created sriptableObject by first adding new items to the list in the inspector, dragging and dropping those tile assets in the corresponding place, and giving those a name.
    Add a reference to that scriptableObject in the script that needs to add those tiles during runtime.
    I believe you might want to save your project everytime you modify one of those scriptableObjects (not entirely sure, might need confirmation).

    You should now be able to use that list, and search for tiles using their names or their order number in the list, to call SetTile(Vector2int position, Tilebase tile) on your tilemap. It should be quicker and easier than searching for the tileAsset directly in your asset folder by code to then set those during runtime, and would prevent you from having to add those tiles manually to every prefab that will require those. It would also fit well in a static class or singleton meant to hold a reference to that kind of asset.


    With a bit more editor scripting, you could make the scriptableObject to automatically take and sort all the tileassets in a certain folder, name them automatically, and other things that might help a lot when you need to reproduce that kind of steps often (I guess it's possible to grab all the tiles included in a tilepalette).
     
    Last edited: Aug 13, 2019
    pbavinck likes this.
  6. aybarsmete1

    aybarsmete1

    Joined:
    Oct 26, 2019
    Posts:
    43
    Hey, if you are still using this forum please answer me. I am trying to do that thing, but I don't see whats wrong. Can you check my code?
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Tilemaps;
    3.  
    4. public class ingameBuild : MonoBehaviour
    5. {
    6.     public Tile highlightTile;
    7.     public Tilemap highlightMap;
    8.     [SerializeField]
    9.  
    10.  
    11.     // do late so that the player has a chance to move in update if necessary
    12.     private void Update()
    13.     {
    14.         // get current grid location
    15.         Vector3Int currentCell = highlightMap.WorldToCell(transform.position);    
    16.         // if the position has changed
    17.         if(Input.GetMouseButtonDown(0))
    18.             highlightMap.SetTile(currentCell, highlightTile);
    19.         }
    20.     }
    21.  
    22.  
     
  7. prichmond

    prichmond

    Joined:
    Feb 19, 2020
    Posts:
    1
    You need to use TileBase:
    Code (CSharp):
    1. public TileBase highlightTile;
     
  8. unity_oSxh7qlfF2rSxw

    unity_oSxh7qlfF2rSxw

    Joined:
    Apr 19, 2020
    Posts:
    1
  9. AngryProgrammer

    AngryProgrammer

    Joined:
    Jun 4, 2019
    Posts:
    490
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.Tilemaps;
    4.  
    5. public class GridManager : MonoBehaviour
    6. {
    7.     // If you have more layers to handle then do a List<Tilemap>
    8.     public Tilemap tilemap;
    9.  
    10.     // If you have a lot of tiles, think about some list, dictionary or structure
    11.     public TileBase tileLand;
    12.     public TileBase tileWater;
    13.  
    14.     // Sample terrain to be generated
    15.     List<List<int>> gameWorld = new List<List<int>>
    16.     {
    17.         new List<int> { 0, 0, 0, 0, 0},
    18.         new List<int> { 0, 1, 1, 1, 0},
    19.         new List<int> { 0, 1, 1, 1, 0},
    20.         new List<int> { 0, 1, 1, 1, 0},
    21.         new List<int> { 0, 0, 0, 0, 0},
    22.     };
    23.  
    24.     void Start()
    25.     {
    26.         for(int x = 0; x < gameWorld.Count; x++)
    27.         {
    28.             for(int y = 0; y < gameWorld[x].Count; y++)
    29.             {
    30.                 tilemap.SetTile(new Vector3Int(x, y, 0), (gameWorld[x][y] == 0 ? tileWater : tileLand));
    31.             }
    32.         }
    33.     }
    34. }
    35.  
     
Thread Status:
Not open for further replies.