- Home /
Question by
nursedayuksel · Nov 09, 2020 at 02:42 PM ·
unity 2dspawnprefabstilemapplatformer
How to spawn multiple prefabs - Tilemap
Good day everyone! I'm trying to build my second game in Unity and it's a 2d platformer game.
I successfully managed to randomly generate my scene with Tilemaps using a script.
As my next task, I want to spawn gems (Collectible prefabs) at random locations in my scene, and I want them to spawn above my tiles so they wont overlap. How can I do this? I've approached this using different methods, however I was successful in creating multiple spawns, so I'd really appreciate the help. :)
I'll attach my script below for generating my scene:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class GenerateTerrain : MonoBehaviour
{
int[,] mapArray;
Tilemap tilemap;
public TileBase tile;
public int terrainWidth, terrainHeight;
// Start is called before the first frame update
void Start()
{
tilemap = GetComponent<Tilemap>();
GenerateMap();
}
void GenerateMap()
{
float seed = UnityEngine.Random.Range(.1f, 1f);
mapArray = GenerateArray(terrainWidth, terrainHeight, true);
RenderMap(PerlinNoiseSmooth(mapArray, seed, 3), tilemap, tile);
}
public static int[,] GenerateArray(int width, int height, bool empty)
{
int[,] map = new int[width, height];
for (int x = 0; x < map.GetUpperBound(0); x++)
{
for (int y = 0; y < map.GetUpperBound(1); y++)
{
if (empty)
{
map[x, y] = 0;
}
else
{
map[x, y] = 1;
}
}
}
return map;
}
public static void RenderMap(int[,] map, Tilemap tilemap, TileBase tile)
{
//Clear the map (ensures we dont overlap)
tilemap.ClearAllTiles();
//Loop through the width of the map
for (int x = 0; x < map.GetUpperBound(0); x++)
{
//Loop through the height of the map
for (int y = 0; y < map.GetUpperBound(1); y++)
{
// 1 = tile, 0 = no tile
if (map[x, y] == 1)
{
tilemap.SetTile(new Vector3Int(x, y, 0), tile);
}
}
}
}
public static void UpdateMap(int[,] map, Tilemap tilemap) //Takes in our map and tilemap, setting null tiles where needed
{
for (int x = 0; x < map.GetUpperBound(0); x++)
{
for (int y = 0; y < map.GetUpperBound(1); y++)
{
//We are only going to update the map, rather than rendering again
//This is because it uses less resources to update tiles to null
//As opposed to re-drawing every single tile (and collision data)
if (map[x, y] == 0)
{
tilemap.SetTile(new Vector3Int(x, y, 0), null);
}
}
}
}
public static int[,] PerlinNoise(int[,] map, float seed)
{
int newPoint;
//Used to reduced the position of the Perlin point
float reduction = 0.5f;
//Create the Perlin
for (int x = 0; x < map.GetUpperBound(0); x++)
{
newPoint = Mathf.FloorToInt((Mathf.PerlinNoise(x, seed) - reduction) * map.GetUpperBound(1));
//Make sure the noise starts near the halfway point of the height
newPoint += (map.GetUpperBound(1) / 2);
for (int y = newPoint; y >= 0; y--)
{
map[x, y] = 1;
}
}
return map;
}
public static int[,] PerlinNoiseSmooth(int[,] map, float seed, int interval)
{
//Smooth the noise and store it in the int array
if (interval > 1)
{
int newPoint, points;
//Used to reduced the position of the Perlin point
float reduction = 0.5f;
//Used in the smoothing process
Vector2Int currentPos, lastPos;
//The corresponding points of the smoothing. One list for x and one for y
List<int> noiseX = new List<int>();
List<int> noiseY = new List<int>();
//Generate the noise
for (int x = 0; x < map.GetUpperBound(0); x += interval)
{
newPoint = Mathf.FloorToInt((Mathf.PerlinNoise(x, (seed * reduction))) * map.GetUpperBound(1));
noiseY.Add(newPoint);
noiseX.Add(x);
}
points = noiseY.Count;
//Start at 1 so we have a previous position already
for (int i = 1; i < points; i++)
{
//Get the current position
currentPos = new Vector2Int(noiseX[i], noiseY[i]);
//Also get the last position
lastPos = new Vector2Int(noiseX[i - 1], noiseY[i - 1]);
//Find the difference between the two
Vector2 diff = currentPos - lastPos;
//Set up what the height change value will be
float heightChange = diff.y / interval;
//Determine the current height
float currHeight = lastPos.y;
//Work our way through from the last x to the current x
for (int x = lastPos.x; x < currentPos.x; x++)
{
for (int y = Mathf.FloorToInt(currHeight); y > 0; y--)
{
map[x, y] = 1;
}
currHeight += heightChange;
}
}
}
else
{
//Defaults to a normal Perlin gen
map = PerlinNoise(map, seed);
}
return map;
}
}
Comment
Your answer
Follow this Question
Related Questions
Having issue with enemy ai shooting 0 Answers
Problem: Random Instantiating more than one prefab? 1 Answer
How do you rotate a tile? 1 Answer
Tilemap Glitching 0 Answers
Serious performance issues 0 Answers