当前位置:网络安全 > 【Unity实战】随机地下城第一代-随机生成地下城初稿(含源代码)

【Unity实战】随机地下城第一代-随机生成地下城初稿(含源代码)

  • 发布:2023-09-30 10:58

先来看看最终效果


#使用素材
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加载场景SceneManagerGetActiveScene()名称 ; ChangePointPos(){//先执行一次do,如果为false则退出,如果为true则继续执行 Direction )随机.范围(0, 4);  方向{情况方向. 上位置+=  矢量30,)  y 偏移, 0);中断 情况方向.向下点 .位置+= Vector3(0, -y偏移,  0);情况方向.向左点 .位置 +=  Vector3(-x偏移,  , 0);断裂;情况方向..位置+=  Vector3(x偏移,0,0); 打破;}}同时 (如果位置已创建()); }//判断位置是否已有房间public bool IfPositionCreated(){foreach  (游戏对象 g 房间){如果(g.变换.位置== .位置) 返回; }返回 ;} }

脚本挂载参数修改及运行效果

优化

如果你想用这里找到的最远的房间作为boss房间,你会发现有时不符合要求

理论上我们需要找到最合适的房间条件:

  • 如果可以的话,应该是只有一扇门的房间
  • 距离初始房间最远的距离
  • 不能有任何房间需要经过‘最终房间’才能到达
    根据这个想法,我们可以现在把找到的最远的房间作为boss战前的奖励房间或者准备房间,在最远的房间附近生成一个boss房间

开始添加代码

空白开始(){//....//以最远的房间为起点,围绕它创建一个Boss房间= endRoom transform;ChangePointPos();//改变点的位置bo ssRoom = 实例化(roomPrefab,.位置, 四元数.恒等式);房间 .添加(bossRoom.获取组件 <房间>());bossRoom.获取组件<SpriteRenderer> ().颜色=  bossColor ;
}

房间代码

使用系统收藏
使用 系统.集合.通用;
使用 UnityEngine
使用 UnityEngineUI公共  班级 房间 :单一行为{公共 游戏对象门_右,门_左 ,门向上,门向下; //用于存放各个位置的门 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 (房间右)门号++;}}

修改RoomGenerate

为了调用和修改房间的值
把房间列表类型改一下

公共 列表<房间>房间 =  列表<房间>();

生成对应的墙壁

使用系统收藏
使用 系统.集合.通用;
使用 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[]偏移= {  Vector30 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);开关 ( 方向 ){情况方向.位置+=矢量30 y 偏移, 0);断裂;情况方向.0, -y偏移,0); 断裂情况方向..位置+=Vector3-x偏移,0,0);断裂 ;情况方向..位置+= Vector3(xOffs)et,0,0);断裂 ;}}同时如果位置已创建位置;}//判断该位置是否有房间public bool IfPositionCreatedVector3)  位置){foreach ( var 房间  房间{if (房间.游戏对象 .变换.位置==位置返回 true;}返回;}公共设置房间房间新房间, Vector3 roomPosition){//判断对应方向是否有其他房间新房间.房间右= 如果位置已创建(房间位置+   Vector3(x偏移,00新房间房间左=  如果位置已创建(房间位置 +  Vector3() -x偏移,0,0 ));新房间.房间向上=如果位置已创建房间位置 +  Vector30 y偏移 0));新房间. roomDown = 如果位置已创建(roomPosition +矢量30-y偏移,0));//生成对应的墙壁预制体var wallPrefabName = GetWallType(newRoom.roomUp, 新房间房间向下新房间房间左,新房间.房间右);var wallPrefab = wallType.GetType().GetField(wallPrefabName) .GetValuewallType as 游戏对象;实例化(墙预制件,房间位置,四元数.身份) ;}//获取对应墙public 字符串 GetWallTypebool 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
}

最终效果

相关文章