#使用素材
https://www.sychzs.cn/download/qq_36303853/87712757
导入房间图片素材并配置图片信息
点击精灵编辑器开始剪切图片
{img_4 : aHR0chHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuLzZlZDU3ZmZmYWRlYTQwNTNhZjI4ZmRhNjM5YWFiOWE5LnBuZw==/}
白色背景图片模拟房间预设
思路:创建一个空的GameObject作为创建房间的点,并设置坐标(0,0,0)。每个房间创建后,随机判断顶部、底部、右侧是否有房间。如果没有,则创建一个新房间;如果已经有房间,则再次随机切换周围四个方向。代码如下
使用系统。收藏;
使用 系统.集合.通用;
使用 UnityEngine;//房间生成器
公共 类 房间生成 : 单一行为{公共 enum 方向 {向上,向下,向左、右};公共方向 方向;//房间[标题("房间信息")]公共游戏对象 roomPfab ; //房间预制件 public int roomNumber; //生成房号 公共 颜色 开始颜色, endColor ; //起始房间颜色和结束房间颜色 private GameObject endRoom;//最后一个房间 [ 标题("位置控制")]公共变换点;//点public float //偏移public 列表<游戏对象> 房间 =新列表<游戏对象>( );无效开始 (){对于(int我= 0; i < roomNumber; i++){//在点位置生成房间游戏对象房间=实例化(roomPrefab,点.位置 ,四元数.身份) ;房间.添加(房间); //改变点位置ChangePointPos() ;}//修改第一个房间颜色rooms[0] .GetComponent<SpriteRenderer >().颜色=开始颜色 ; //循环寻找远端房间endRoom =房间[0];foreach(var房间在房间){ // sqrMagnitude 指向量长度的平方,用于比较向量之间的大小 if(room.transform.位置.sqr幅度>endRoom.变换。 位置.sqr幅度){endRoom = room;}}endRoom .GetComponent<SpriteRenderer>( ).颜色= endColor;}void更新 (){//点击空格即可重新加载当前场景 if (输入.GetKey(按键代码.空格)) {SceneManager。加载场景(SceneManager。 GetActiveScene()。名称 ; ChangePointPos(){//先执行一次do,如果为false则退出,如果为true则继续执行 Direction )随机.范围(0, 4); (方向){情况方向. 上:点。位置+= 新 矢量3(0,) y 偏移, 0);中断 ;情况方向.向下:点 .位置+=新 Vector3(0, -y偏移, 0);断;情况方向.向左:点 .位置 += 新 Vector3(-x偏移, , 0);断裂;情况方向.右:点.位置+= 新 Vector3(x偏移,0,0); 打破;}}同时 (如果位置已创建()); }//判断位置是否已有房间public bool IfPositionCreated(){foreach (游戏对象 g 在房间){如果(g.变换.位置==点 .位置) 返回真; }返回 假;} }
脚本挂载参数修改及运行效果
如果你想用这里找到的最远的房间作为boss房间,你会发现有时不符合要求
理论上我们需要找到最合适的房间条件:
开始添加代码
空白开始(){//....//以最远的房间为起点,围绕它创建一个Boss房间点= endRoom 。 transform;ChangePointPos();//改变点的位置bo ssRoom = 实例化(roomPrefab,点.位置, 四元数.恒等式);房间 .添加(bossRoom.获取组件 <房间>());bossRoom.获取组件<SpriteRenderer> ().颜色= bossColor ;
}
使用系统。收藏;
使用 系统.集合.通用;
使用 UnityEngine;
使用 UnityEngine。UI;公共 班级 房间 :单一行为{公共 游戏对象门_右,门_左 ,门向上,门向下; //用于存放各个位置的门 public bool roomRight, roomLeft , 房间向上, 房间向下 ? public int stepToStart ;//距起始点public的网格距离 int门号;/ /当前房间的门数/入口数void 开始(){/ /对应方向的门是否为显示,与对应方向是否有其他房间Door_right.SetActive (roomRight);门_左 .设置活动(房间左);门向上。 设置活动(roomUp); .设置活动(roomDown); }公共voidUpdateRoom() ){//计算距初始点的网格距离步骤ToStart = (int)(Mathf) .Abs(变换.位置.x /18)+ Mathf.Abs(变换) .位置.y / 9));文字.文字= 步骤开始.ToString();if (房间向上)门号 ++;if (房间向下)门号++;如果 (房间左)门号++;if (房间右)门号++;}}
为了调用和修改房间的值
把房间列表类型改一下
公共 列表<房间>房间 = 新 列表<房间>();
生成对应的墙壁
使用系统。收藏;
使用 系统.集合.通用;
使用 UnityEngine;使用 UnityEngine.场景管理;//房间生成发生器
公共 类 房间生成 : 单一行为{公共 enum 方向 {向上,向下,向左、右};公共方向 方向;//房间[标题("房间信息")]公共游戏对象 roomPfab ; //房间预制件 public int roomNumber; //生成房号 公共 颜色 开始颜色, endColor , bossColor; //开始房间、结束房间、Boss房间颜色private 游戏对象 endRoom; //最后一个房间private 游戏对象 bossRoom;//老板的房间[标题( 「位置控制」)]公共变换点; //点公共浮动 xOffset , yOffset;//偏移public 列表<房间>房间 = 新 列表<房间>();公共墙型 wallType;void 开始() {对于(int i = 0; i < 房间号; i++){/ /点位置生成房间GameObject房间=实例化( roomPrefab,点.位置,四元数.身份);房间。 添加(房间。获取组件<房间>());//改变点位置ChangePointPos();}//装修后的第一个房间房间[0].GetComponent<Sprite渲染器>( ).color = startColor;//流通室结束房间=房间[0 ].游戏对象;foreach( var 房间 中 房间) 房间.变换.位置.sqr幅度> endRoom.变换.位置.sqr幅度){结束房间=房间。 游戏对象;}}endRoom.获取组件 <Sprite渲染器>()。最远的房间为起点,周围创建boss房间Vector3[]偏移= { 新 Vector3(0, y 偏移, 0) )、 新 Vector3 (0, -y偏移, 0), 新 矢量3( -x偏移, 0, 0),新矢量3(x偏移,0,0)} ;foreach (Vector3偏移量 在 偏移量) {Vector3 bossPosition = endRoom.变换.位置;boss位置+=偏移;if (!如果职位已创建(老板职位) )){bossRoom = 实例化(roomPrefab, boss位置,四元数。 身份);房间.添加(bossRoom.获取组件<房间>());boss房间.GetComponent<Sprite渲染器>().颜色= bossColor;break;}}//设置房间墙壁foreach ( var房间在房间){设置房间(房间,房间 .变换.位置) ;}}void更新() {//点击空格,重新加载当前场景if (输入.获取密钥(KeyCode.空间)){场景管理器.加载场景(场景管理器.获取活动场景().姓名); }}公共 void ChangePointPos() ){//先执行一次do,while while为false退出,是真的 继续做do{方向 = (直接离子)随机.范围( 0, 4);开关 ( 方向 ){情况方向。 上:点.位置+= 新矢量3(0, y 偏移, 0);断裂;情况方向.下:点。 0, -y偏移,0); 断裂;情况方向.左:点.位置+= 新Vector3(-x偏移,0,0);断裂 ;情况方向.右:点.位置+=新 Vector3(xOffs)et,0,0);断裂 ;}}同时( 如果位置已创建(点。位置));}//判断该位置是否有房间public bool IfPositionCreated(Vector3) 位置){foreach ( var 房间 在 房间){if (房间.游戏对象 .变换.位置==位置)返回 true;}返回假;}公共空 设置房间(房间新房间, Vector3 roomPosition){//判断对应方向是否有其他房间新房间.房间右= 如果位置已创建(房间位置+ 新 Vector3(x偏移,0,0));新房间。 房间左= 如果位置已创建(房间位置 + 新 Vector3() -x偏移,0,0 ));新房间.房间向上=如果位置已创建(房间位置 + 新 Vector3(0, y偏移, 0));新房间. roomDown = 如果位置已创建(roomPosition +新矢量3(0,-y偏移,0));//生成对应的墙壁预制体var wallPrefabName = GetWallType(newRoom.roomUp, 新房间。房间向下,新房间。 房间左,新房间.房间右);var wallPrefab = wallType.GetType().GetField(wallPrefabName) .GetValue(wallType) as 游戏对象;实例化(墙预制件,房间位置,四元数.身份) ;}//获取对应墙public 字符串 GetWallType(bool wallUp) , bool wallDown, bool wallLeft, bool wallRight){字符串 WallPrefabName = "Wall_";if (wallUp)WallPrefabName += "U";if (wallRight)WallPrefabName += "R";if(wallDown )WallPrefabName += "D";if (wallLeft)WallPrefabName += "L";返回WallPrefabName; }}[系统.可序列化]
公共 类 墙壁类型{公共 游戏对象Wall_U,Wall_R 、 Wall_D、 Wall_L、 Wall_UR、 Wall_UD、 Wall_UL、 Wall_RD、 Wall_RL、 Wall_DL、 Wall_URD、 Wall_URL、 Wall_RDL、 Wall_URDL、 Wall_UDL;
}
最终效果