- Home /
How would I instantiate rooms made of a ruletile as part of a rogue-like random level generation system and have the ruletile affected by the other spawned rooms rule tiles?
Hello. I have finished BlackThornProd's tutorial series on creating rogue like random level generation and it is working fine, however as my rooms are made up of tiles using a rule tile, the rule tiles wouldnt recognise neighbouring rooms as the room prefab had a seperate tilemap. How would I go about merging them/making them recognise eachother as part of the rule tile? Or is there a better way to do this alltogether? Sorry if this is a stupid question, I have a decent amount of unity experience but this is the first time I am using tilemaps and I have spent way too long googling this to no avail... Thank you in advance. I will show my code below if you dont want to watch/havent watched the tutorial. Apologies for the very messy and inneficient code, I havent gotten to cleaning it up yet.
LevelGeneration.cs: this spawns the main path
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class LevelGeneration : MonoBehaviour
{
[Header("Spawning References")]
public Transform[] startingPositions;
public GameObject[] rooms; // 0 = LR, 1 = LRB, 2 = LRT, 3 = LRTB, I know that ints arent the best and it would be much better to use enums however I was following the tutorial very closely as every time i tried to edit it before finished something would break. I will fix this later, apologies for making it harder to understand
public GameObject startingRoomInternals;
public LayerMask roomLayer;
[Header("Stats")]
public float moveAmount = 10f;
public float timeBetweenRoom = 0.25f;
[Header("Bounds")]
public float minX;
public float maxX;
public float minY;
[Header("Resetting Tilemap")]
public Tilemap tilemapMain;
private float currentTimeBetweenRoom;
private int direction;
[HideInInspector] public bool stopGeneration = false;
private int downCounter;
private void Start()
{
int randStartingPos = Random.Range(0, startingPositions.Length);
transform.position = startingPositions[randStartingPos].position;
SpawnRoomAndInternals(rooms[0], startingRoomInternals);
if(randStartingPos == 0)
{
direction = Random.Range(2, 5);
}
else if(randStartingPos == startingPositions.Length - 1)
{
direction = Random.Range(1, 4);
}
else
{
direction = Random.Range(1, 5);
}
}
private void Update()
{
if(currentTimeBetweenRoom <= 0 && !stopGeneration)
{
Move();
currentTimeBetweenRoom = timeBetweenRoom;
}
else
{
currentTimeBetweenRoom -= Time.deltaTime;
}
}
private void Move()
{
Vector2 newPos;
switch (direction)
{
//RIGHT
case 1:
case 2:
if(transform.position.x < maxX - moveAmount)
{
downCounter = 0;
newPos = new Vector2(transform.position.x + moveAmount, transform.position.y);
transform.position = newPos;
int rand = Random.Range(0, rooms.Length);
SpawnRoomAndInternals(rooms[rand]);
direction = Random.Range(1, 6);
if(direction == 3)
{
direction = 2;
}
else if(direction == 4)
{
direction = 5;
}
}
else
{
direction = 5;
}
break;
//LEFT
case 3:
case 4:
if (transform.position.x > minX + moveAmount)
{
newPos = new Vector2(transform.position.x - moveAmount, transform.position.y);
transform.position = newPos;
int rand = Random.Range(0, rooms.Length);
SpawnRoomAndInternals(rooms[rand]);
direction = Random.Range(3, 6);
downCounter = 0;
}
else
{
direction = 5;
}
break;
//DOWN
case 5:
downCounter++;
if (transform.position.y > minY + moveAmount)
{
Collider2D roomDetection = Physics2D.OverlapCircle(transform.position, 1, roomLayer);
RoomType roomTypeTemp = roomDetection.GetComponent<RoomType>();
if (roomTypeTemp.roomType != 1 && roomTypeTemp.roomType != 3)
{
roomTypeTemp.DestroyRoom();
if (downCounter >= 2)
{
SpawnRoomAndInternals(rooms[3]);
}
else
{
int randBottomRoom = Random.Range(1, 4); // adding 1 due to second parameter being exclusive
if (randBottomRoom == 2)
{
randBottomRoom = 1;
}
SpawnRoomAndInternals(rooms[randBottomRoom]);
}
}
newPos = new Vector2(transform.position.x, transform.position.y - moveAmount);
transform.position = newPos;
int rand = Random.Range(2, 4); // adding 1 due to second parameter being exclusive
SpawnRoomAndInternals(rooms[rand]);
direction = Random.Range(1, 6);
}
else
{
stopGeneration = true;
}
break;
}
}
public void SpawnRoomAndInternals(GameObject roomTemplate)
{
SpawnRoomAndInternals(roomTemplate, null);
}
public void SpawnRoomAndInternals(GameObject roomTemplate, GameObject roomInternals)
{
Transform temp = Instantiate(roomTemplate, transform.position, Quaternion.identity).transform;
if (roomInternals != null)
{
GameObject tempInternals = Instantiate(roomInternals, temp).gameObject;
//MoveTilesToTilemap(tempInternals.GetComponentInChildren<Tilemap>(), tilemapMain);
}
//MoveTilesToTilemap(temp.GetComponentInChildren<Tilemap>(), tilemapMain);
}
//this function is a first attempt that didnt work
private void MoveTilesToTilemap(Tilemap tilemapA, Tilemap tilemapB)
{
TileBase[] tilesA = tilemapA.GetTilesBlock(tilemapA.cellBounds);
Vector3Int[] positions = new Vector3Int[tilemapA.cellBounds.size.x * tilemapA.cellBounds.size.y];
for (int index = 0; index < positions.Length; index++)
{
positions[index] = new Vector3Int(index % tilemapA.cellBounds.size.x, index / tilemapA.cellBounds.size.x, 0);
}
Destroy(tilemapA.transform.parent.gameObject);
tilemapB.SetTiles(positions, tilesA);
}
}
RoomType.cs: this goes on each roomtemplate prefab and is to identify the type of room it is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomType : MonoBehaviour
{
public int roomType; // again, i know i should use enums or consts so as to give each number a name but I havent gotten to it yet as i was following the tutorial very closely
public void DestroyRoom()
{
Destroy(this.gameObject);
}
}
SpawnRooms.cs: this is for spawning random rooms off main path so there isnt alot of empty space
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnRooms : MonoBehaviour
{
public LayerMask roomLayer;
public LevelGeneration levelGeneration;
private void Update()
{
Collider2D roomDetection = Physics2D.OverlapCircle(transform.position, 1, roomLayer);
if(roomDetection == null && levelGeneration.stopGeneration)
{
int rand = Random.Range(0, levelGeneration.rooms.Length);
Instantiate(levelGeneration.rooms[rand], transform.position, Quaternion.identity);
}
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How can I get the world position of a Tile? 2 Answers
[Solved] Isometric Rule Tiles not Following Guidelines. 0 Answers