Home > other >  Random tile spawning in Unity
Random tile spawning in Unity

Time:09-06

Ok so here is my process of trying to find the solution for this. What I want to do: I want to spawn tiles ( like flower ) randomly on the tilemap, but I can't spawn flower at the walls' position or the player position right ? so I will get all the tiles' position that already existed, get their position, add them to a list. Therefore, when I spawn the flowers, the position of them won't coincide with the wall. But one problem, there isn't any property named position when I add the walls' position. I got stuck, how to get the walls' position or do you guys have any idea besides this ?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class test : MonoBehaviour
{
    [ SerializeField ]GameObject Deco;
    List<Vector2> xyPositionOfExistedTile;
    // Start is called before the first frame update
    void Start()
    {
        xyPositionOfExistedTile = new List<Vector2>();
        Tilemap tilemap = Deco.GetComponent<Tilemap>();
        TileBase [] tiles = tilemap.GetTilesBlock(tilemap.cellBounds);
        foreach (TileBase tile in tiles)
        {
            xyPositionOfExistedTile.Add();
        }
    }

}

A link to reference

CodePudding user response:

Assuming you are not implementing your own custom tiles, you can compare the sprites.

[SerializeField] 
GameObject Deco;

[SerializeField, Tooltip("Tile sprite to compare against")]
Sprite wallSprite;

List<Vector2> xyPositionOfExistedTile;

void Start() {
    xyPositionOfExistedTile = new List<Vector2>();
    Tilemap tilemap = Deco.GetComponent<Tilemap>();
    TileBase[] tiles = tilemap.GetTilesBlock(tilemap.cellBounds);

    foreach (TileBase tile in tiles) {
        if ((tile as Tile)?.sprite != wallSprite) { 
            // Not a custom tile or wall tile
        }
    }
}

Alternatively, you can create your own custom tiles to store data (Ex: bool flag if wall). Search online for Unity scriptable tiles.

CodePudding user response:

I found a new way to solve this problem => First: Get all tiles that existed ( Check this answer )
Then use a loop to spawn tile ( you can reference to the existing tiles'position check if the position of the tile you want to spawn not equal the existing one then spawn it )
Ok so here is my script ( feel free to comment if something is wrong )

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class SpawnTileRandomly : MonoBehaviour
{
    [SerializeField] int numberOfTiles;
    Tilemap tileMap_C;

    // Start is called before the first frame update
    void Start()
    {
        GenerateRandomTile(numberOfTiles);
    }
    void GenerateRandomTile(int numberOfTiles)
    {

        List<Vector3> xyPositionOfExistedTile = new List<Vector3>();
        tileMap_C = GetComponent<Tilemap>();
        for (int i = tileMap_C.cellBounds.xMin; i < tileMap_C.cellBounds.xMax; i  )
        {
            for (int j = tileMap_C.cellBounds.yMin; j < tileMap_C.cellBounds.yMax; j  )
            {
                Vector3Int localTilePosition = new Vector3Int(i, j, (int)tileMap_C.transform.position.z); 
//Get the position of tile on tile coordinate
                Vector3 tilePosition = tileMap_C.CellToWorld(localTilePosition); 
// Transform it to world  coordinate
                if (tileMap_C.HasTile(localTilePosition);)
                {
                    xyPositionOfExistedTile.Add(tilePosition);

                }
            }
        }
        for (int i = 0; i < numberOfTiles; i  )
        {
            var positionToSpawn = new Vector3(Random.Range(tileMap_C.cellBounds.xMin, tileMap_C.cellBounds.xMax), Random.Range(tileMap_C.cellBounds.yMin, tileMap_C.cellBounds.yMax), tileMap_C.transform.position.z);
            foreach (var Vector in xyPositionOfExistedTile)
            {
                if (positionToSpawn == Vector)
                {
                    positionToSpawn = new Vector3(Random.Range(tileMap_C.cellBounds.xMin, tileMap_C.cellBounds.xMax), Random.Range(tileMap_C.cellBounds.yMin, tileMap_C.cellBounds.yMax), tileMap_C.transform.position.z); 
// if it equals the existing tiles' position, then renew it 
                }
            }
            tileMap_C.SetTile(tileMap_C.WorldToCell(positionToSpawn), GameAssets.Instance.tileToSpawn);
        }
    }
}
  • Related