亲宝软件园·资讯

展开

Unity 随机房间地图生成

汐夜 人气:0

无论是在迷宫还是类似于地牢的游戏地图中,利用程序来生成每次都不一样的地图是一件叫人兴奋不已的事。

这时我们需要解决两个非常重要的随机事件:

1.在一定范围内随机出各不相同但又不能互相重叠的房间

2.优美生成连接这些房间的通道

 

基本的UML思路图:

 

 

这次我们先讨论如何快速生成符合各种随机要求的房间。

一般来说,一个房间的高度是一个相对固定的值,可以根据面板上的参数进行必要的调整,而真正参与随机的应该是房间的长,宽和位置。

 

建立房间的数据结构,根据需求可以随时补充和添加:

 1 using System.Collections.Generic;
 2 using UnityEngine;
 3 
 4 public class RoomData
 5 {
 6     public int Id;
 7     //房间的Transform等属性
 8     public RoomTran RoomTran;
 9     //该房间的战斗类型
10     public RoomBattleType BattleType;
11     //该房间与哪些其余房间互相连接
12     public List<RoomData> CrossRooms;
13     //房间内的怪物列表
14     public List<GameObject> Monsters;
15     //是否是端点房间
16     public bool bEndRoom;
17     //是否是主路径房间
18     public bool bMainCrossRoom;
19 }
20 
21 public class RoomTran
22 {
23     public int Length;
24     public int Width;
25     //长宽中心点
26     public Vector2Int CenterPos;
27     //高度位置
28     public float PosY;
29 }
30 
31 public enum RoomBattleType
32 {
33     Rest,
34     NormalBattle,
35     BossBattle
36 }

 

RoonBuilder属性和控制参数:

 1     //建筑单位方块
 2     public GameObject BuildUnit;
 3 
 4     //房间高度值
 5     public int FixedUnitHeight;
 6     //生成的房间层数
 7     public int LayerCount;
 8     //长宽随机范围
 9     public Vector2Int GenRange;
10 
11     //随机类型
12     public RoomRandType RandType;
13     //随机的房间形状类型
14     public RoomShapeType Shape;
15 
16     //房间大小的随机列表,用于枚举随机
17     public List<Vector2Int> RoomRandSizes = new List<Vector2Int>();
18 
19     //随机的房间最大面积
20     public int MaxRoomArea;
21     //最大随机数量(随机试验次数)
22     public int MaxRoomCount;
23 
24     //最小边长度
25     private int MinRoomEdge;
26     //最大长宽比
27     public int MaxLengthWidthScale = 2;
28 
29     //标准方向
30     Vector3Int Dx = new Vector3Int(1, 0, 0);
31     Vector3Int Dy = new Vector3Int(0, 1, 0);
32     Vector3Int Dz = new Vector3Int(0, 0, 1);
33 
34     //建筑单位标签
35     const string S_TAG = "Unit";
36 
37     private MapSystem MapManager;

 

单房间轮廓生成:

 1     /// <summary>
 2     /// 生成单一房间的轮廓
 3     /// </summary>
 4     /// <param name="centerPos">房间中点位置</param>
 5     /// <param name="length">长</param>
 6     /// <param name="width">宽</param>
 7     /// <param name="parent">父物体</param>
 8     void GenOneRoom(Vector3 centerPos, int length, int width, Transform parent = null)
 9     {
10         var to = new Vector3(length - 1, FixedUnitHeight - 1, width - 1) * .5f;
11 
12         //顶点
13         var ned = centerPos - to;
14         var fod = centerPos + to;
15 
16         var v3 = new Vector3(ned.x, fod.y, ned.z);
17         var v4 = new Vector3(ned.x, fod.y, fod.z);
18         var v5 = new Vector3(ned.x, ned.y, fod.z);
19 
20         var v6 = new Vector3(fod.x, ned.y, ned.z);
21         var v7 = new Vector3(fod.x, ned.y, fod.z);
22         var v8 = new Vector3(fod.x, fod.y, ned.z);
23 
24         //顶点位置(8个)
25         InsSetPos(ned, parent);
26         InsSetPos(fod, parent);
27         InsSetPos(v3, parent);
28         InsSetPos(v4, parent);
29         InsSetPos(v5, parent);
30         InsSetPos(v6, parent);
31         InsSetPos(v7, parent);
32         InsSetPos(v8, parent);
33 
34         //12条棱(4*3)
35         //长
36         InsOneEdge(length, ned, Dx, parent);
37         InsOneEdge(length, v3, Dx, parent);
38         InsOneEdge(length, v4, Dx, parent);
39         InsOneEdge(length, v5, Dx, parent);
40         //高
41         InsOneEdge(FixedUnitHeight, ned, Dy, parent);
42         InsOneEdge(FixedUnitHeight, v5, Dy, parent);
43         InsOneEdge(FixedUnitHeight, v6, Dy, parent);
44         InsOneEdge(FixedUnitHeight, v7, Dy, parent);
45         //宽
46         InsOneEdge(width, ned, Dz, parent);
47         InsOneEdge(width, v3, Dz, parent);
48         InsOneEdge(width, v6, Dz, parent);
49         InsOneEdge(width, v8, Dz, parent);
50     }
51 
52     //生成一条边上的建筑单位但不包含顶点位置
53     void InsOneEdge(int edge, Vector3 v, Vector3 dir, Transform parent = null)
54     {
55         //忽略首尾单位
56         for (int i = 1; i < edge - 1; i++)
57         {
58             InsSetPos(v + i * dir, parent);
59         }
60     }
61 
62     void InsSetPos(Vector3 pos, Transform parent = null)
63     {
64         var ins = Instantiate(BuildUnit);
65         ins.transform.position = pos;
66         ins.transform.parent = parent;
67     }

这里唯一值得注意的地方是房间顶点位置的单位不要重复生成。(因为想偷懒的话真的很容易重复Orz)。

 

随机RoonTran结构:

 1     RoomTran RanRoomTran(Vector3 centerPos)
 2     {
 3         var rt = new RoomTran();
 4 
 5         switch (RandType)
 6         {
 7             case RoomRandType.AllRand:
 8                 int temp;
 9                 var oe = MaxRoomArea / MinRoomEdge;
10                 switch (Shape)
11                 {
12                     case RoomShapeType.LengthMain:
13                         rt.Length = Random.Range(MinRoomEdge + 1, oe + 1);
14                         temp = MaxRoomArea / rt.Length;
15                         if (temp >= rt.Length)
16                             rt.Width = Random.Range(MinRoomEdge, rt.Length);
17                         else
18                             rt.Width = Random.Range(MinRoomEdge, temp + 1);
19                         break;
20                     case RoomShapeType.WidthMain:
21                         rt.Width = Random.Range(MinRoomEdge + 1, oe + 1);
22                         temp = MaxRoomArea / rt.Width;
23                         if (temp >= rt.Width)
24                             rt.Length = Random.Range(MinRoomEdge, rt.Width);
25                         else
26                             rt.Length = Random.Range(MinRoomEdge, temp + 1);
27                         break;
28                     case RoomShapeType.Coustom:
29                         rt.Length = Random.Range(MinRoomEdge, oe + 1);
30                         temp = MaxRoomArea / rt.Length;
31                         rt.Width = Random.Range(MinRoomEdge, temp + 1);
32                         break;
33                 }
34                 break;
35             case RoomRandType.EnumRand:
36                 var rc = RoomRandSizes.Count;
37                 if (rc == 0)
38                 {
39                     //未填写时设定随机默认值
40                     rt.Length = 3;
41                     rt.Width = 3;
42                 }
43                 else
44                 {
45                     var ridx = Random.Range(0,rc);
46                     var t = RoomRandSizes[ridx];
47                     if (t.x < 3 || t.y < 3)
48                     {
49                         //填写错误时设定随机默认值
50                         rt.Length = 3;
51                         rt.Width = 3;
52                     }
53                     else
54                     {
55                         switch (Shape)
56                         {
57                             case RoomShapeType.LengthMain:
58                                 rt.Length = t.x > t.y ? t.x : t.y;
59                                 rt.Width = t.x < t.y ? t.x : t.y;
60                                 break;
61                             case RoomShapeType.WidthMain:
62                                 rt.Width = t.x > t.y ? t.x : t.y;
63                                 rt.Length = t.x < t.y ? t.x : t.y;
64                                 break;
65                             case RoomShapeType.Coustom:
66                                 rt.Length = Random.value < .5f ? t.x : t.y;
67                                 rt.Width = t.y == rt.Length ? t.x : t.y;
68                                 break;
69                         }         
70                     }
71                 }
72                 break;
73         }
74    
75         rt.CenterPos = new Vector2Int(Random.Range((int)(centerPos.x - GenRange.x * .5f), (int)(centerPos.x + GenRange.x * .5f)),
76             Random.Range((int)(centerPos.z - GenRange.y * .5f), (int)(centerPos.z + GenRange.y * .5f)));
77 
78         rt.PosY = centerPos.y;
79 
80         var roomCenter = new Vector3(rt.CenterPos.x, rt.PosY, rt.CenterPos.y);
81 
82         //射线检测重叠
83         if (RayRoomCheck(roomCenter, rt.Length, rt.Width))
84         {
85             return null;
86         }
87         return rt;
88     }

用的是射线检测重叠,生成了重叠的房间就会被视作是一次失败的随机试验,之前尝试过直接用物理系统推开失败了,可能是使用有误,如果有知道原因的欢迎与笔者分享,共同进步,有更好的避免矩形重叠的算法当然更好

(无奈笔者没能想出来):

 1     //生成房间前射线检测下范围内有无其他房间
 2     bool RayRoomCheck(Vector3 cp, int length, int width)
 3     {
 4         bool result = false;
 5         //长宽至少留一格间隙,高度与地板格对齐
 6         var to = new Vector3(length + 1, FixedUnitHeight - 1, width + 1) * .5f;
 7         var ned = cp - to;
 8 
 9         var vx2 = ned + new Vector3(0, 0, width + 1) * .5f;
10         var vx3 = ned + new Vector3(0, 0, width + 1);
11 
12         var vx4 = ned + new Vector3(length + 1, 0, width * .5f + .5f);
13         var vx5 = ned + new Vector3(length + 1, 0, width + 1);
14 
15         var vz2 = ned + new Vector3(length + 1, 0, 0) * .5f;
16         var vz3 = ned + new Vector3(length + 1, 0, 0);
17 
18         var vz4 = ned + new Vector3(length * .5f + .5f, 0, width + 1);
19         var vz5 = ned + new Vector3(length + 1, 0, width + 1);
20 
21         result =
22         //4组射线,每组3条
23         RayCast(ned, Dx, length + 1, S_TAG) ||
24         RayCast(vx2, Dx, length + 1, S_TAG) ||
25         RayCast(vx3, Dx, length + 1, S_TAG) ||
26 
27         RayCast(vx4, Dx * -1, length + 1, S_TAG) ||
28         RayCast(vx5, Dx * -1, length + 1, S_TAG) ||
29         RayCast(vz3, Dx * -1, length + 1, S_TAG) ||
30 
31         RayCast(ned, Dz, width + 1, S_TAG) ||
32         RayCast(vz2, Dz, width + 1, S_TAG) ||
33         RayCast(vz3, Dz, width + 1, S_TAG) ||
34 
35         RayCast(vz4, Dz * -1, width + 1, S_TAG) ||
36         RayCast(vz5, Dz * -1, width + 1, S_TAG) ||
37         RayCast(vx3, Dz * -1, width + 1, S_TAG);
38 
39         return result;
40     }

这里将射线的起点和终点都延长了一格,是为了避免两个生成的房间贴得太紧,这样至少每个房间与其它房间间隔一个单位格或以上。

 

完整的房间结构生成脚本:

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.Events;
  5 
  6 public enum RoomRandType
  7 {
  8     //全随机
  9     AllRand,
 10     //枚举大小随机
 11     EnumRand
 12 }
 13 
 14 public enum RoomShapeType
 15 {
 16     //宽>=长
 17     WidthMain,
 18     //长>=宽
 19     LengthMain,
 20     //自定义,无形状要求
 21     Coustom
 22 }
 23 //x-length z-width y-height
 24 
 25 public class RoomBuilder : MonoBehaviour
 26 {
 27     //建筑单位方块
 28     public GameObject BuildUnit;
 29 
 30     //房间高度值
 31     public int FixedUnitHeight;
 32     //生成的房间层数
 33     public int LayerCount;
 34     //长宽随机范围
 35     public Vector2Int GenRange;
 36 
 37     //随机类型
 38     public RoomRandType RandType;
 39     //随机的房间形状类型
 40     public RoomShapeType Shape;
 41 
 42     //房间大小的随机列表,用于枚举随机
 43     public List<Vector2Int> RoomRandSizes = new List<Vector2Int>();
 44 
 45     //随机的房间最大面积
 46     public int MaxRoomArea;
 47     //最大随机数量(随机试验次数)
 48     public int MaxRoomCount;
 49 
 50     //最小边长度
 51     private int MinRoomEdge;
 52     //最大长宽比
 53     public int MaxLengthWidthScale = 2;
 54 
 55     //标准方向
 56     Vector3Int Dx = new Vector3Int(1, 0, 0);
 57     Vector3Int Dy = new Vector3Int(0, 1, 0);
 58     Vector3Int Dz = new Vector3Int(0, 0, 1);
 59 
 60     //建筑单位标签
 61     const string S_TAG = "Unit";
 62 
 63     private MapSystem MapManager;
 64 
 65     void Awake()
 66     {
 67         MapManager = GetComponent<MapSystem>();
 68     }
 69 
 70     public IEnumerator GenRooms(Vector3Int centerPos,UnityAction complete)
 71     {
 72         var temp = (int)Mathf.Sqrt(MaxRoomArea * 1.0f / MaxLengthWidthScale);
 73         MinRoomEdge = temp > 3 ? temp : 3;
 74 
 75         //每层至少1
 76         for (int i = 1; i <= LayerCount; i++)
 77         {
 78             SetGenOneRoom(centerPos, i);
 79             yield return new WaitForSeconds(.1f);
 80         }
 81 
 82         //超过的随机布置
 83         var oc = MaxRoomCount - LayerCount;
 84         if (oc > 0)
 85         {
 86             for (int i = 1; i <= oc; i++)
 87             {
 88                 var r = Random.Range(1, LayerCount + 1);
 89                 SetGenOneRoom(centerPos, r);
 90                 yield return new WaitForSeconds(.1f);
 91             }
 92         }
 93 
 94         //所有房间生成完成后发送一个委托信号,以便后续创建房间数据和计算必要连接
 95         complete();
 96     }
 97 
 98     void SetGenOneRoom(Vector3Int cp, int r)
 99     {
100         var layerCenter = cp - new Vector3(0, (LayerCount - 2 * r + 1) * .5f * FixedUnitHeight, 0);
101 
102         var rt = RanRoomTran(layerCenter);
103         if (rt != null)
104         {
105             var roomCenter = new Vector3(rt.CenterPos.x, rt.PosY, rt.CenterPos.y);
106 
107             GameObject temp = new GameObject(r.ToString());
108             temp.transform.position = roomCenter;
109             temp.tag = S_TAG;
110 
111             //给生成的房间添加碰撞盒子并设置大小
112             GenOneRoom(roomCenter, rt.Length, rt.Width, temp.transform);
113             var bc = temp.AddComponent<BoxCollider>();
114             bc.size = new Vector3(rt.Length, FixedUnitHeight, rt.Width);
115 
116             //目前用物理方式似乎难以推开重叠的房间,可能是哪里使用方法有误,改为用用射线检测解决...
117             //var rb = temp.AddComponent<Rigidbody>();
118             //rb.useGravity = false;
119             //rb.drag = Mathf.Infinity;
120             //rb.constraints = RigidbodyConstraints.FreezePositionY;
121             //rb.freezeRotation = true;
122 
123             //将房间数据存入临时列表
124             MapManager.GenRooms.Add(rt);
125             MapManager.UnCrossRooms.Add(rt);
126         }
127     }
128 
129     RoomTran RanRoomTran(Vector3 centerPos)
130     {
131         var rt = new RoomTran();
132 
133         switch (RandType)
134         {
135             case RoomRandType.AllRand:
136                 int temp;
137                 var oe = MaxRoomArea / MinRoomEdge;
138                 switch (Shape)
139                 {
140                     case RoomShapeType.LengthMain:
141                         rt.Length = Random.Range(MinRoomEdge + 1, oe + 1);
142                         temp = MaxRoomArea / rt.Length;
143                         if (temp >= rt.Length)
144                             rt.Width = Random.Range(MinRoomEdge, rt.Length);
145                         else
146                             rt.Width = Random.Range(MinRoomEdge, temp + 1);
147                         break;
148                     case RoomShapeType.WidthMain:
149                         rt.Width = Random.Range(MinRoomEdge + 1, oe + 1);
150                         temp = MaxRoomArea / rt.Width;
151                         if (temp >= rt.Width)
152                             rt.Length = Random.Range(MinRoomEdge, rt.Width);
153                         else
154                             rt.Length = Random.Range(MinRoomEdge, temp + 1);
155                         break;
156                     case RoomShapeType.Coustom:
157                         rt.Length = Random.Range(MinRoomEdge, oe + 1);
158                         temp = MaxRoomArea / rt.Length;
159                         rt.Width = Random.Range(MinRoomEdge, temp + 1);
160                         break;
161                 }
162                 break;
163             case RoomRandType.EnumRand:
164                 var rc = RoomRandSizes.Count;
165                 if (rc == 0)
166                 {
167                     //未填写时设定随机默认值
168                     rt.Length = 3;
169                     rt.Width = 3;
170                 }
171                 else
172                 {
173                     var ridx = Random.Range(0,rc);
174                     var t = RoomRandSizes[ridx];
175                     if (t.x < 3 || t.y < 3)
176                     {
177                         //填写错误时设定随机默认值
178                         rt.Length = 3;
179                         rt.Width = 3;
180                     }
181                     else
182                     {
183                         switch (Shape)
184                         {
185                             case RoomShapeType.LengthMain:
186                                 rt.Length = t.x > t.y ? t.x : t.y;
187                                 rt.Width = t.x < t.y ? t.x : t.y;
188                                 break;
189                             case RoomShapeType.WidthMain:
190                                 rt.Width = t.x > t.y ? t.x : t.y;
191                                 rt.Length = t.x < t.y ? t.x : t.y;
192                                 break;
193                             case RoomShapeType.Coustom:
194                                 rt.Length = Random.value < .5f ? t.x : t.y;
195                                 rt.Width = t.y == rt.Length ? t.x : t.y;
196                                 break;
197                         }         
198                     }
199                 }
200                 break;
201         }
202    
203         rt.CenterPos = new Vector2Int(Random.Range((int)(centerPos.x - GenRange.x * .5f), (int)(centerPos.x + GenRange.x * .5f)),
204             Random.Range((int)(centerPos.z - GenRange.y * .5f), (int)(centerPos.z + GenRange.y * .5f)));
205 
206         rt.PosY = centerPos.y;
207 
208         var roomCenter = new Vector3(rt.CenterPos.x, rt.PosY, rt.CenterPos.y);
209 
210         //射线检测重叠
211         if (RayRoomCheck(roomCenter, rt.Length, rt.Width))
212         {
213             return null;
214         }
215         return rt;
216     }
217 
218     //生成房间前射线检测下范围内有无其他房间
219     bool RayRoomCheck(Vector3 cp, int length, int width)
220     {
221         bool result = false;
222         //长宽至少留一格间隙,高度与地板格对齐
223         var to = new Vector3(length + 1, FixedUnitHeight - 1, width + 1) * .5f;
224         var ned = cp - to;
225 
226         var vx2 = ned + new Vector3(0, 0, width + 1) * .5f;
227         var vx3 = ned + new Vector3(0, 0, width + 1);
228 
229         var vx4 = ned + new Vector3(length + 1, 0, width * .5f + .5f);
230         var vx5 = ned + new Vector3(length + 1, 0, width + 1);
231 
232         var vz2 = ned + new Vector3(length + 1, 0, 0) * .5f;
233         var vz3 = ned + new Vector3(length + 1, 0, 0);
234 
235         var vz4 = ned + new Vector3(length * .5f + .5f, 0, width + 1);
236         var vz5 = ned + new Vector3(length + 1, 0, width + 1);
237 
238         result =
239         //4组射线,每组3条
240         RayCast(ned, Dx, length + 1, S_TAG) ||
241         RayCast(vx2, Dx, length + 1, S_TAG) ||
242         RayCast(vx3, Dx, length + 1, S_TAG) ||
243 
244         RayCast(vx4, Dx * -1, length + 1, S_TAG) ||
245         RayCast(vx5, Dx * -1, length + 1, S_TAG) ||
246         RayCast(vz3, Dx * -1, length + 1, S_TAG) ||
247 
248         RayCast(ned, Dz, width + 1, S_TAG) ||
249         RayCast(vz2, Dz, width + 1, S_TAG) ||
250         RayCast(vz3, Dz, width + 1, S_TAG) ||
251 
252         RayCast(vz4, Dz * -1, width + 1, S_TAG) ||
253         RayCast(vz5, Dz * -1, width + 1, S_TAG) ||
254         RayCast(vx3, Dz * -1, width + 1, S_TAG);
255 
256         return result;
257     }
258 
259     bool RayCast(Vector3 ori, Vector3 dir, float mD, string tag)
260     {
261         Ray ray = new Ray(ori, dir);
262         RaycastHit info;
263         if (Physics.Raycast(ray, out info, mD))
264         {
265             if (info.transform.tag == tag)
266                 return true;
267         }
268         return false;
269     }
270 
271     /// <summary>
272     /// 生成单一房间的轮廓
273     /// </summary>
274     /// <param name="centerPos">房间中点位置</param>
275     /// <param name="length">长</param>
276     /// <param name="width">宽</param>
277     /// <param name="parent">父物体</param>
278     void GenOneRoom(Vector3 centerPos, int length, int width, Transform parent = null)
279     {
280         var to = new Vector3(length - 1, FixedUnitHeight - 1, width - 1) * .5f;
281 
282         //顶点
283         var ned = centerPos - to;
284         var fod = centerPos + to;
285 
286         var v3 = new Vector3(ned.x, fod.y, ned.z);
287         var v4 = new Vector3(ned.x, fod.y, fod.z);
288         var v5 = new Vector3(ned.x, ned.y, fod.z);
289 
290         var v6 = new Vector3(fod.x, ned.y, ned.z);
291         var v7 = new Vector3(fod.x, ned.y, fod.z);
292         var v8 = new Vector3(fod.x, fod.y, ned.z);
293 
294         //顶点位置(8个)
295         InsSetPos(ned, parent);
296         InsSetPos(fod, parent);
297         InsSetPos(v3, parent);
298         InsSetPos(v4, parent);
299         InsSetPos(v5, parent);
300         InsSetPos(v6, parent);
301         InsSetPos(v7, parent);
302         InsSetPos(v8, parent);
303 
304         //12条棱(4*3)
305         //长
306         InsOneEdge(length, ned, Dx, parent);
307         InsOneEdge(length, v3, Dx, parent);
308         InsOneEdge(length, v4, Dx, parent);
309         InsOneEdge(length, v5, Dx, parent);
310         //高
311         InsOneEdge(FixedUnitHeight, ned, Dy, parent);
312         InsOneEdge(FixedUnitHeight, v5, Dy, parent);
313         InsOneEdge(FixedUnitHeight, v6, Dy, parent);
314         InsOneEdge(FixedUnitHeight, v7, Dy, parent);
315         //宽
316         InsOneEdge(width, ned, Dz, parent);
317         InsOneEdge(width, v3, Dz, parent);
318         InsOneEdge(width, v6, Dz, parent);
319         InsOneEdge(width, v8, Dz, parent);
320     }
321 
322     //生成一条边上的建筑单位但不包含顶点位置
323     void InsOneEdge(int edge, Vector3 v, Vector3 dir, Transform parent = null)
324     {
325         //忽略首尾单位
326         for (int i = 1; i < edge - 1; i++)
327         {
328             InsSetPos(v + i * dir, parent);
329         }
330     }
331 
332     void InsSetPos(Vector3 pos, Transform parent = null)
333     {
334         var ins = Instantiate(BuildUnit);
335         ins.transform.position = pos;
336         ins.transform.parent = parent;
337     }
338 }

 

在MapSystem中可以在房间结构生成完后创建一个默认的数据结构:

 1     public void RandRoomDatas()
 2     {
 3         if (RoomBuilder == null||MapData ==null)
 4             return;
 5 
 6         RoomBuilder.StartCoroutine(RoomBuilder.GenRooms(MapData.MapCenter,()=> 
 7         {
 8             CreatRoomData();
 9             RandRoomCrosses();
10         }));
11     }
12 
13     void CreatRoomData()
14     {
15         for (int i = 1; i < GenRooms.Count + 1; i++)
16         {
17             var rd = new RoomData();
18             rd.Id = i;
19             rd.RoomTran = GenRooms[i - 1];
20             rd.BattleType = RoomBattleType.NormalBattle;
21             if (rd.Id == 1)
22                 rd.BattleType = RoomBattleType.Rest;
23             rd.CrossRooms = new List<RoomData>();
24             rd.Monsters = new List<GameObject>();
25             rd.bEndRoom = false;
26             rd.bMainCrossRoom = false;
27 
28             MapData.RoomDataDic.Add(rd.Id, rd);
29         }
30     }

 

效果图:(单层-枚举列表随机)

 

 单层(全随机-长条形房间随机):

 

 多层(层数5)(自定义-全随机):

 

 参考资料:

https://indienova.com/indie-game-development/rooms-and-mazes-a-procedural-dungeon-generator/?tdsourcetag=s_pctim_aiomsg

https://mp.weixin.qq.com/s/3yM-mAAXq_fX5tcy82s0uQ

加载全部内容

相关教程
猜你喜欢
用户评论