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();
}
}
}
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);
}
}
}