Tile-based room spawning (Unity3d)

Started by
1 comment, last by haegarr 8 years, 7 months ago

The title mostly says it.

Hello, I'm attempting to make a tile-based room spawner for my mini game. The idea is to spawn the room in tiles, so right now I have a simple room spawner that actually spawns a room by randomly choosing a number for the length and the width of the room (and also height but ill save that for later). Currently it is spawning it like it should but my goal is to have randomly generating rooms with either columns and stuff, Maybe ill show a picture as a picture says a thousand words.

That picture explains my ideal goal, now how can I do dis?? Heres my current code.


#pragma strict

var floorBoundary : GameObject;
var wallBoundary : GameObject;

var tileOffest : float = 0.0f;
var wallOffest : float = 0.0f;
var maxRoomSize : int = 10;

function Start () {
	var width : GameObject = new GameObject("Width");
	width.tag = "width";
	
	Random.seed = Random.value * 500;
	var roomWSizer : int = Random.Range(1, maxRoomSize);
	var roomLSizer : int = Random.Range(0, maxRoomSize);
	
	for(var i : int = 0; i < roomWSizer; i++){ //width
		var posW = Vector3(tileOffest * i, 0.0f, 0.0f);
		
		var floorBoundW : GameObject = Instantiate(floorBoundary, posW, transform.rotation);
		var RoofBoundW : GameObject = Instantiate(floorBoundary, Vector3(posW.x, 9.4f, posW.z), transform.rotation);
		
		floorBoundW.transform.SetParent(width.transform);
		RoofBoundW.transform.SetParent(width.transform);
		RoofBoundW.transform.localScale.y = -1;
	}
	
	for(var j : int = 0; j < roomLSizer; j++){ //length
		var posL = Vector3(0.0f, 0.0f, tileOffest * j + tileOffest);
		var roomL : GameObject = Instantiate(width, posL, transform.rotation);
	}
	
	var roomWidth : int = roomWSizer + roomWSizer;
	var roomLength : int = (roomLSizer + 1) * 2;
	
	//var wFindG : GameObject = GameObject.FindGameObjectWithTag("width");
	//var wFindA : GameObject = wFindG.transform.;
	for(var w1 : int = 0; w1 < roomWidth; w1++){ //wall width 1
		var wall1pos = Vector3(((tileOffest/2) * w1) - 6, wallOffest, -(tileOffest/2));
		var wall1rot = Quaternion.Euler(90,0,0);
		var wall1bound : GameObject = Instantiate(wallBoundary, wall1pos, wall1rot);
		wall1bound.transform.SetParent(width.transform);
	}
	
	for(var l1 : int = 0; l1 < roomLength; l1++){ //wall width 1
		var wall3pos = Vector3( -tileOffest/2, wallOffest, ((tileOffest/2) * l1) - 6);
		var wall3rot = Quaternion.Euler(90,90,0);
		var wall3bound : GameObject = Instantiate(wallBoundary, wall3pos, wall3rot);
		wall3bound.transform.SetParent(width.transform);
	}
	
	for(var l2 : int = 0; l2 < roomLength; l2++){ //wall width 1
		var wall4pos = Vector3( (tileOffest/2) * roomLength/2, wallOffest, ((tileOffest/2) * l2) - 6);
		var wall4rot = Quaternion.Euler(90,-90,0);
		var wall4bound : GameObject = Instantiate(wallBoundary, wall4pos, wall4rot);
		wall4bound.transform.SetParent(width.transform);
	}
}

Advertisement

There's tons of information in the web about procedural generation, specially of dungeons and such.

Here's one lecture I attended that was very helpful (It's from Unity's Unite conference, but the concepts and algorithms are not unity-specific)

One example of more "organic" rooms made by modifying rectangular rooms can be found in this GDC video about Shattered Planet. Look for "geometry decay" to remove tiles and, if you wish, "crumbly tiles" for adding some (also the crumbly tiles shown in the video are just decoration). In fact, the way chosen was to assign a probability to each tile where tiles in corners have a higher probability to decay then tiles on an edge, and tiles on an edge have a greater probability than tiles in the inside. Tiles that need to stay have 0 probability. Then iterate the tile grid and generate a PSN for each one and set the tile to nil if the PSN is below the tile's decay probability value.

In the end you have a 2D array where you store at which index you have a tile at all and, if so, which tile. Then iterate the array and determine whether the tile has a neighbor at some of its 4 edges. For a room grid of possibly n by m tiles, the tile at index [i,j] has no neighbor

with 0 <= i <= n and 0 <= j <= m :

* to the north if j == m-1 orElse tile[i,j+1] == nil

* to the south if j == 0 orElse tile[i,j+1] == nil

* to the west if i == 0 orElse tile[i-1,j] == nil

* to the east if i == n-1 orElse tile[i+1,j] == nil

(notice that I've used the orElse operator here to denote that the tile[] must be checked only if the condition part on the left hand side is false).

For each tile and each of its edges place a suitable wall if there is no neighbor.

This topic is closed to new replies.

Advertisement