1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > unity随机方向的代码_基于 Unity 的 Roguelike 随机房间生成的方法

unity随机方向的代码_基于 Unity 的 Roguelike 随机房间生成的方法

时间:2020-02-13 08:28:53

相关推荐

unity随机方向的代码_基于 Unity 的 Roguelike 随机房间生成的方法

本文主要是为了实现各种随机大小不一样的方块基础房间,便于 Roguelike 游戏地图使用,希望对各位独立游戏的新手有所帮助,同时也希望各位大牛可以给出宝贵意见。

由于我的思路是地图=基础房间+特殊房间(宝箱房、挑战房、任务房、Boss房),本文暂不涉及特殊房间以及个性化的多边形房间。

房间要求

房间大小基本符合一定的长宽比;

单个房间不会有重叠;

房间间保留一定间隙,方便后续填充围墙与走廊;

整体房间分布不是线性的,方便后续连通的多样性;

核心思路

根据游戏的操作,定下一个房间的长宽比;(本文的房间长宽比为1.6-2.0)

根据长宽比,取得1号房间的长与宽X1,Y1;

取得1号房间的中心点O1;

对O1进行一个四向的随机偏移,得到O2;

取得2号房间的长于宽X2,Y2;

利用射线检测,若无重叠则可生成,若有,重复4、5、6步骤直到可以生成;

铺设地毯、围墙等基本装饰物,完成。

效果图

房间概览图

房间细节图

代码

C#代码如下,包含三个主体方法:取得房间半径、取得房间中心点和生成房间。

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class MapManager : MonoBehaviour

{

// Use this for initialization

private float roomRadii;//房间的长度半径

private float roomRatio;//由宽决定长的比值

public float roomX;//房间的长

public float roomY;//房间的宽

public float roomXi;//房间i的长

public float roomYi;//房间i的宽

public int roomXMin = 10;

public int roomXMax = 16;

public Vector2 posO;//房间中心点

int roomIndex = 0;

public List roomPos = new List();//创建储存房间有效位置的二维表

public List offset = new List();//创建储存房间中心点的二维表

public GameObject[] floorArray;

public Transform roomHolder;

void Start()

{

roomPos.Clear();//后续房间内的所有可用位置都会添加到这个二维表里

SetRoomXY();

posO = new Vector2(0, 0);

//生成12个房间进行检验

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

CreateRoom(posO);

}

void SetRoomXY()//取得房间长宽半径

{

roomRadii = Random.Range(roomXMin, roomXMax);//标准值取随机值

roomRatio = Random.Range(16, 20);

roomRatio = roomRatio / 10;

roomX = 2 * roomRadii;//房间的长是标准值的两倍,因此就是偶数

roomY = roomX / roomRatio;//房间的宽由长来决定

roomY = Mathf.Round(roomY);//对Y取整数

if (roomY % 2 != 0)//对Y进行判断,取偶数 {

roomY += 1;

}

}

Vector2 CreateCenter(Vector2 pos)//对中心点进行偏移

{

int x = Random.Range(2 * roomXMin + 1, 2 * roomXMax + 1);

offset.Clear();

for (int i = 2 * roomXMin + 1; i <= 2 * roomXMax + 1; i++) {

for (int j = 30; j <= 50; j++) {

offset.Add(new Vector2(i, j));

}

}

//现在取出一个符合基本规则的中心点偏移量

int index = Random.Range(0, offset.Count);

float offsetX = offset[index].x;

float offsetY = offset[index].y;

Vector2 pos2 = new Vector2(0, 0);

int o = Random.Range(0, 4);

if (o == 0) {

pos2 = pos + new Vector2(offsetX, offsetY);

}

if (o == 1) {

pos2 = pos + new Vector2(offsetX, -offsetY);

}

if (o == 2) {

pos2 = pos + new Vector2(-offsetX, offsetY);

}

if (o == 3) {

pos2 = pos + new Vector2(-offsetX, -offsetY);

}

//现在取得了下一个房间中心

posO = pos2;

return posO;

}

void CreateRoom(Vector2 pos)//生成基础房间(铺设地板)

{

CreateCenter(pos);//对上一个房间的中心点进行偏移,取得本次房间的中心点

pos = posO;

SetRoomXY();//取得当前要生成房间的长宽半径

roomXi = roomX;

roomYi = roomY;

int isRoom = 0;

//对预生成的房间先进行是否有房间的检测(基于房间九点:左上,中上,右上,左中……)

Vector2 checkPos1 = new Vector2(pos.x - roomXi, pos.y - roomYi) + new Vector2(-4, -4);

Vector2 checkPos2 = new Vector2(pos.x - roomXi, pos.y + roomYi) + new Vector2(-4, 4);

Vector2 checkPos3 = new Vector2(pos.x + roomXi, pos.y - roomYi) + new Vector2(-4, 4);

Vector2 checkPos4 = new Vector2(pos.x + roomXi, pos.y + roomYi) + new Vector2(4, 4);

Vector2 checkPos6 = new Vector2(pos.x, pos.y - roomYi) + new Vector2(0, -4);

Vector2 checkPos7 = new Vector2(pos.x, pos.y + roomYi) + new Vector2(0, 4);

Vector2 checkPos8 = new Vector2(pos.x + roomXi, pos.y) + new Vector2(4, 0);

Vector2 checkPos9 = new Vector2(pos.x - roomXi, pos.y) + new Vector2(-4, 0);

RaycastHit2D hit1 = Physics2D.Linecast(checkPos1, checkPos1, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit2 = Physics2D.Linecast(checkPos2, checkPos2, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit3 = Physics2D.Linecast(checkPos3, checkPos3, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit4 = Physics2D.Linecast(checkPos4, checkPos4, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit5 = Physics2D.Linecast(pos, pos, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit6 = Physics2D.Linecast(checkPos6, checkPos6, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit7 = Physics2D.Linecast(checkPos7, checkPos7, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit8 = Physics2D.Linecast(checkPos8, checkPos8, 1 << LayerMask.NameToLayer("floor"));

RaycastHit2D hit9 = Physics2D.Linecast(checkPos9, checkPos9, 1 << LayerMask.NameToLayer("floor"));

if (hit1.collider == null && hit2.collider == null && hit3.collider == null && hit4.collider == null && hit5.collider == null && hit6.collider == null && hit7.collider == null && hit8.collider == null && hit9.collider == null)

{

isRoom += 1;

}

if (isRoom >= 0)

{

if (isRoom == 0) {

CreateRoom(pos);

} else {

roomIndex += 1;//可以生成房间的时候,给房间记上标记

roomHolder = new GameObject("Room" + roomIndex).transform;//给父类添加名字

//为地板进行二维数组赋值

for (float x = pos.x - roomXi; x <= pos.x + roomXi; x++) {

for (float y = pos.y - roomYi; y <= pos.y + roomYi; y++) {

Vector2 posFloor = new Vector2(x, y);

roomPos.Add(new Vector2(x, y));

int i = Random.Range(0, floorArray.Length);

GameObject go = Instantiate(floorArray[i], posFloor, Quaternion.identity);

go.transform.SetParent(roomHolder);

}

}

}

}

}

}

关于连通与特殊房,我的想法是因为生成的时候给房间以及进行序号标记了(1-12),先依次对中心点进行走廊生成,以及门生成,确保主干道连通,再取随机房间进行连通丰富路线(如2和4,6和8),在这个基础上加入预设的特殊房。(特殊房应该有足够的设计量,因此不适宜用随机。)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。