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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Can I define a 2x2 Rule Tile?

Discussion in '2D' started by arcanee36, Feb 27, 2023.

  1. arcanee36

    arcanee36

    Joined:
    Dec 29, 2022
    Posts:
    2
    I am trying to create procedurally generates levels and I am using empty game objects as possible spawn points. On each of these spawn points I have a C# script, that sets a tile in my tilemap.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Tilemaps;
    6.  
    7. public class SpawnObject : MonoBehaviour {
    8.  
    9.     [SerializeField] Tilemap tilemap;
    10.     [SerializeField] RuleTile[] groundTiles;
    11.  
    12.  
    13.     void Awake() {
    14.         tilemap = GameObject.FindGameObjectWithTag("MainFloor").GetComponent<Tilemap>();
    15.     }
    16.  
    17.     void Start() {
    18.         int rand = Random.Range(0, groundTiles.Length);
    19.         tilemap.SetTile(Vector3Int.FloorToInt(transform.position), groundTiles[rand]);
    20.     }
    21.  
    22.     //This callback is called before destroying the game object. I need to cleanup all the tiles
    23.     public void OnDisable() {
    24.         if (tilemap != null) {
    25.             tilemap.SetTile(Vector3Int.FloorToInt(transform.position), null);
    26.         }
    27.     }
    28.  
    29. }
    This just places one 1x1 rule Tile. Is it possible to create bigger chunks that I can place in similiar way? I would like to randomly place 2x2 blocks, or T shaped bloks in the level.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,957
    The above script implicitly passes its world position in as the TileMap position, so I'm pretty sure it only works if the Tilemap is at (0,0,0) and if the tile sizes are precisely 1x1 in world units. At least that's how I understand it.

    Aaaaaanyway,not important. The key is the above implicitly also just fills a 1x1 tile with a single statement.

    You would need to replace that single stamp with code to stamp the pattern of rule tiles that you want, eg, like a 2x2 cluster of ruletiles. How this stamping would ultimately cause the RuleTiles to behave I cannot say, as I haven't mucked much with them.

    Obviously you'd want an object that represents N number of rule tiles in relative positions to each other, like 2x2 or the T you mentioned, and the code above would choose randomly from those object possibilities to act.
     
  3. arcanee36

    arcanee36

    Joined:
    Dec 29, 2022
    Posts:
    2
    So the only way would be to use the SetTile function multiple times with different coordinations? Something like
    Code (CSharp):
    1.  
    2. tilemap.SetTile(Vector3Int.FloorToInt(new Vector3(transform.position.x-1, transform.position.y, transform.position.z)), groundTiles[rand]);
    3. tilemap.SetTile(Vector3Int.FloorToInt(new Vector3(transform.position.x+1, transform.position.y, transform.position.z)), groundTiles[rand]);
    4. tilemap.SetTile(Vector3Int.FloorToInt(transform.position), groundTiles[rand]);
    5. tilemap.SetTile(Vector3Int.FloorToInt(new Vector3(transform.position.x, transform.position.y+1, transform.position.z)), groundTiles[rand]);
    6.  
    That just feels cumbersome, is there really not a better way to do it?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,957
    I wouldn't write it that way. :)

    How about:

    Code (csharp):
    1. Vector2Int[] offsets = new Vector2Int[] {
    2.   new Vector2Int( 0,+1),
    3.   new Vector2Int( 0,-1),
    4.   new Vector2Int(-1, 0),
    5.   new Vector2Int(+1, 0),
    6. };
    and then spin that with a for loop and add to the position.

    EDIT : Woop... my bad, it should be (0,0), (1,0), (1, 1), (0,1)
     
  5. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    You could use
    Tilemap.SetTiles
    and
    Tilemap.SetTilesBlock
    to set multiple Tiles at once.