unity下多层随机迷宫构建

2023-11-03

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Maze : MonoBehaviour
{
    public GameObject[] wallPrefab; // 墙壁预制体
    public GameObject[] pathPrefab; // 路径预制体
    public GameObject stairsPrefab; // 梯子预制体
    public GameObject treePrefab; // 树预制体
    public int mazeWidth = 10; // 迷宫宽度
    public int mazeHeight = 10; // 迷宫高度
    public int mazeLayer = 3; // 迷宫层
    public int layerHeight = 14; // 层高度
    public int mazeStairsMax = 5; // 迷宫高度
    public float cellSize = 10f; // 单元格大小

    private int[][][] maze; // 迷宫二维数组

    private void Start()
    {
        maze = new int[mazeLayer][][];
        for (int l = 0; l < mazeLayer; l++)
        {
            maze[l] = creatMap(mazeWidth, mazeHeight);
        }
        AddStairs();
        for (int l = 0; l < mazeLayer; l++)
        {
            GameObject la = new GameObject("la" + l);
            la.transform.parent = transform;
            for (int i = 1; i < maze[l].Length - 1; i++)
            {
                for (int j = 1; j < maze[l][i].Length - 1; j++)
                {
                    switch (maze[l][i][j])
                    {
                        case 1:
                            if (l == 0)
                            {
                                bool cre = true;
                                for (int m = 1; m < mazeLayer; m++)
                                {
                                    if (i < maze[m].Length && j < maze[m][i].Length && maze[m][i][j] != 1)
                                    {
                                        cre = false;
                                        break;
                                    }
                                }
                                if (cre)
                                {
                                    GameObject wall = Instantiate(wallPrefab[Random.Range(0, wallPrefab.Length)], la.transform);
                                    wall.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
                                }
                            }
                            else
                            {
                                GameObject tree = Instantiate(treePrefab, la.transform);
                                tree.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
                            }
                            break;
                        case 2:
                            GameObject stairs = Instantiate(stairsPrefab, la.transform);
                            stairs.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
                            break;
                        case 3:
                            break;
                        default:
                            GameObject path = Instantiate(GetPath(i,l,j), la.transform);
                            path.transform.localPosition = new Vector3(i * cellSize, l * layerHeight, j * cellSize);
                            break;
                    }
                }
            }
        }
        //StaticBatchingUtility.Combine(gameObject);
    }

    public GameObject GetPath(int i,int l, int j)
    {
        if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            // ┼
            return pathPrefab[0];
        }
        else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            //├
            return pathPrefab[1];
        }
        else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 ||(l > 0 && maze[l - 1][i - 1][j] == 2)))
        {
            // ┤
            return pathPrefab[2];
        }
        else if (maze[l][i][j - 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            // ┴
            return pathPrefab[3];
        }
        else if (maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)) && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            // ┬
            return pathPrefab[4];
        }
        else if (maze[l][i][j + 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            //└
            return pathPrefab[5];
        }
        else if (maze[l][i][j - 1] == 0 && maze[l][i - 1][j] == 0)
        {
            //┌
            return pathPrefab[6];
        }
        else if (maze[l][i][j - 1] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            //┘
            return pathPrefab[7];
        }
        else if (maze[l][i][j + 1] == 0 && (maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)))
        {
            //┐
            return pathPrefab[8];
        }
        else if ( maze[l][i - 1][j] == 0 && (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2))
        {
            //—
            return pathPrefab[9];
        }
        else if (maze[l][i][j - 1] == 0 && maze[l][i][j + 1] == 0)
        {
            //│
            return pathPrefab[10];
        }
        else if ((maze[l][i - 1][j] == 0 || (l > 0 && maze[l - 1][i - 1][j] == 2)))
        {
            //→
            return pathPrefab[11];
        }
        else if (maze[l][i + 1][j] == 0 || maze[l][i + 1][j] == 2)
        {
            //←
            return pathPrefab[12];
        }
        else if (maze[l][i][j - 1] == 0)
        {
            //↑
            return pathPrefab[13];
        }
        else if (maze[l][i][j + 1] == 0)
        {
            //↓
            return pathPrefab[14];
        }
        return pathPrefab[0];
    }
    public void AddStairs()
    {
        for (int l = 0; l < maze.Length - 1; l++)
        {
            List<Vector3Int> list = new List<Vector3Int>();
            for (int i = 1; i < maze[l + 1].Length - 1; i++)
            {
                for (int j = 1; j < maze[l + 1][i].Length - 1; j++)
                {
                    if (maze[l][i][j] == 1 && maze[l + 1][i][j] == 1 && maze[l][i - 1][j] == 0 && maze[l + 1][i + 1][j] == 0)
                    {
                        list.Add(new Vector3Int(l, i, j));
                    }
                }
            }
            if (list.Count > mazeStairsMax)
            {
                for (int i = 0; i < mazeStairsMax; i++)
                {
                    Vector3Int v3 = list[Random.Range(0, list.Count)];
                    maze[v3.x][v3.y][v3.z] = 2;
                    if (maze[0][v3.y][v3.z] == 1)
                    {
                        maze[0][v3.y][v3.z] = 3;
                    }
                }
            }
            else
            {
                for (int i = 0; i < list.Count; i++)
                {
                    Vector3Int v3 = list[i];
                    maze[v3.x][v3.y][v3.z] = 2;
                }
            }
        }
    }

    int[][] mapArr;
    List<int> notAccessed = new List<int>();
    List<int> accessed = new List<int>();

    int rand(int min, int max)
    {
        int num = Mathf.FloorToInt(Random.Range(min, max));
        return num;
    }

    public int[][] creatMap(int r, int c)
    {
        notAccessed.Clear();
        accessed.Clear();
        mapArr = new int[2 * r + 1][];
        for (int i = 0; i < mapArr.Length; i++)
        {
            mapArr[i] = new int[2 * c + 1];
            for (int n = 0; n < mapArr[i].Length; n++)
            {
                if ((n ^ (n - 1)) == 1 && (i ^ (i - 1)) == 1)
                {
                    mapArr[i][n] = 0;                    // 0 表示路
                    notAccessed.Add(0);
                }
                else
                {
                    mapArr[i][n] = 1;                    // 1 表示墙
                }
            }
        }
        int count = r * c;
        int cur = rand(0, count);
        int[] offs = new int[] { -c, c, -1, 1 };         // 四周顶点在notAccessed的偏移量
        int[] offr = new int[] { -1, 1, 0, 0 };                        // 四周顶点在arr的纵向偏移量
        int[] offc = new int[] { 0, 0, -1, 1 };                        // 四周顶点在arr的横向偏移量
        accessed.Add(cur);
        notAccessed[cur] = 1;

        while (accessed.Count < count)
        {
            int tr = Mathf.FloorToInt(cur / c);
            int tc = cur % c;
            int off = -1;

            // 遍历上下左右顶点
            for (int i = 0; i < 4; i++)
            {
                int around = rand(0, 4);
                int nr = tr + offr[around];
                int nc = tc + offc[around];
                if (nr >= 0 && nc >= 0 && nr < r && nc < c && notAccessed[cur + offs[around]] == 0)
                {
                    off = around;
                    break;
                }
            }
            // 四周顶点均被访问,则从已访问的顶点中随机抽取一个为cur
            if (off < 0)
            {
                cur = accessed[rand(0, accessed.Count)];
            }
            else
            {
                tr = 2 * tr + 1;
                tc = 2 * tc + 1;
                mapArr[tr + offr[off]][tc + offc[off]] = 0;
                cur = cur + offs[off];
                notAccessed[cur] = 1;
                accessed.Add(cur);
            }
        }
        return mapArr;
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

unity下多层随机迷宫构建 的相关文章

  • UE4 解决景深效果闪烁问题

    原因 1 模型的垂直竖线 造成抗锯齿算法对竖线的渲染计算 处于一种不稳定的状态 因此闪烁 解决办法 使用LOD 用贴图去替代线条模型 2 材质的法线贴图 当法线贴图含有垂直竖线的纹理效果 也会造成闪烁 比如这种幕墙材质 解决办法 关闭或动态
  • Unity中级客户端开发工程师的进阶之路

    上期UWA技能成长系统之 Unity高级客户端开发工程师的进阶之路 得到了很多Unity开发者的肯定 通过系统的学习 可以掌握游戏性能瓶颈定位的方法和常见的CPU GPU 内存相关的性能优化方法 UWA技能成长系统是UWA根据学员的职业发展
  • FBX导入Unity中模型没有材质的处理

    一 3dMax导出FBX时的注意事项 导出时 确保maps文件存在 里面放着fbx用到的image 二 在Unity中的设置 1 文件拖入Unity的Assets文件夹中 2 查看模型的材质是否存在 如下所示 材质为None 此时拖入sce
  • Unity中按钮检测鼠标状态

    改方法主要是用于按钮检测鼠标的进入 滑出 点击 抬起 长按 长按停止 1 先将下面这个脚本挂载到需要检测鼠标状态的按钮上 using System Collections using System Collections Generic u
  • Unity中实现倒计时的几种方式

    1 Time time using UnityEngine public class TimeTest MonoBehaviour public float secound 10 void Update Timing private flo
  • Unity之获取游戏物体对象或组件的几个方法

    文章目录 前言 通过物体名称获取对象 GameObject Find Transform Find 通过物体标签获取对象 GameObject FindWithTag GameObject FindGameObjectWithTag Gam
  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • unity工程崩溃资源找回

    1 Unity死机未保存场景 当你在Unity中编辑场景 突然死机时 可以在项目文件目录中找到Temp文件夹 双击文件夹 找到 Backupscenes文件夹 把后缀为 backup的文件后缀改为 unity 然后拖进Unity的Proje
  • Unity 键盘控制人物移动——之输入方式代码的编写

    键盘输入 控制人物移动 在我们制作游戏中最常见的需求之一就是使用键盘移动游戏角色 那么我们首先需要获取键盘输入 以下提供两种方法获取键盘 这里尽量通过截图解释让大家理解代码的含义 GetInput void FixedUpdate Move
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w
  • Unity万向节死锁解决方案(2023/12/4)

    1 万向节死锁无法解决 这是因为它的特性就是如此 就像玻璃杯就是玻璃 这不可否认 别钻牛角尖昂 2 大多数情况下欧拉角足够用 例如 CF 摄像机不可能绕z轴旋转 x轴旋转也不会超过九十度 因为那样人物的腰子会被扭断 塔防游戏 保卫萝卜 吃鸡
  • unity3d 自定义的图片无法放入source image中

    须将图片的texture type改为 sprite
  • mixamo根动画导入UE5问题:滑铲

    最近想做一个跑酷游戏 从mixamo下载滑铲动作后 出了很多动画的问题 花了两周时间 终于是把所有的问题基本上都解决了 常见问题 1 动画序列 人物不移动 2 动画序列 人物移动朝向错误 3 蒙太奇 人物移动后会被拉回 4 蒙太奇 动画移动
  • unity小球跟随音乐节奏放大缩小和改变颜色

    放在小球身上 设置对应组件即可 using System Collections using System Collections Generic using Unity VisualScripting using UnityEngine
  • 【Unity】运行时创建曲线(贝塞尔的运用)

    Unity 运行时创建线 贝塞尔的运用 1 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线 2 原理介绍 2 1 曲线的创建 unity建立网格曲线可以参考 Unity程序化网格体 的实现方法 主要分为顶点 三角面 U
  • Unity学习笔记

    一 旋转欧拉角 四元数 Vector3 rotate new Vector3 0 30 0 Quaternion quaternion Quaternion identity quaternion Quaternion Euler rota
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发常用实践操作之按动任意键触发

    接下来一些笔记会对于一些大大小小的实践操作进行记录 希望对你有所帮助 在游戏中 我们经常会遇到一些按动任意键触发的操作 接下来展示核心代码 以下是对于Unity中的操作 使用的UI是NGUI 对于核心操作没有影响 你可以自己置换 void
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接

随机推荐

  • 数学建模写作与排版

    1 2 数学建模 快速入门 上 1 3 数学建模 快速入门 下 写作部分 首页 论文标题 摘要 关键词 一 问题重述 二 问题分析 三 模型假设 四 符号说明 五 模型的建立与求解 六 模型的分析与检验 七 模型的评价 改进和推广 八 参考
  • NFS环境搭建

    NAT模式下 安装NFS sudo apt install nfs kernel server 重启NFS服务器 sudo etc init d nfs kernel server restart 修改配置文件 etc exports 在里
  • 灰色关联分析法

    与灰色预测模型一样 比赛不能优先使用 灰色关联往往可以与层次分析结合使用 层次分析用在确定权重上面 1 确定比较对象 评价对象 就是数据 并且需要进行规范化处理 就是标准化处理 见下面例题的表格数据 和参考数列 评价标准 一般该列数列都是1
  • windows下能搭建php-fpm吗 phpstudy

    这个Windows和Linux系统是不一样的 因为一般nginx搭配php需要php fpm中间件 但是Windows下需要第三方编译 下载的包里有php cgi exe 但不是php fpm如果想在windows上跑php fpm 据说可
  • 【ES】分布式集群

    ES 分布式集群 单节点集群 故障转移 水平扩容 应对故障 路由计算 本文主要参考尚硅谷的资料 少部分自己原创 有错误之处请指出 单节点集群 node 1001配置如下 集群名称 节点之间要保持一致 cluster name my elas
  • C++ PCL库实现最远点采样算法

    最远点采样 Farthest Point Sampling 简称FPS 是点云处理领域中的一种重要算法 用于对点云数据进行快速降采样 最早的最远点采样算法应该是在计算机图形学领域中提出的 用于在三维模型上进行表面重建 随着点云处理技术的发展
  • HDU--1200:To and Fro (字符串)

    1 题目源地址 http acm hdu edu cn showproblem php pid 1200 2 解题代码 include
  • 服务器远程使用什么协议,云服务器远程是什么协议

    云服务器远程是什么协议 内容精选 换一换 弹性云服务器 Elastic Cloud Server 是一种可随时自动获取 计算能力可弹性伸缩的云服务器 可帮助您打造可靠 安全 灵活 高效的应用环境 确保服务持久稳定运行 提升运维效率 WinS
  • Jira 史诗指南 (2022)

    Jira 就是为了完成工作 而 Epics 是实现该目标的一种有价值的方式 一般来说 Epics 适用于顾名思义 不会在一天内完成但会 的工作 史诗 在本指南中 我们将分解什么是 Epics 它们的用途 以及它们的用途 以及如何创建和使用它
  • Qt 应用程序显示页面的方法

    1 在qt窗口中显示页面 1 pro中添加 QT webkitwidgets 2 添加头文件 include
  • Swift4.0 guard,Array,Dictionary

    guard的使用 guard是Swift新增语法 guard语句必须带有else语句当条件表达式为true时候跳过else语句中的内容 执行语句组内容 条件表达式为false时候执行else语句中的内容 跳转语句一般是return brea
  • Web服务器群集:Nginx网页及安全优化

    目录 一 理论 1 Nginx网页优化 2 Nginx安全优化 3 Nginx日志分割 二 实验 1 网页压缩 2 网页缓存 3 连接超时设置 4 并发设置 5 隐藏版本信息 6 脚本实现每月1号进行日志分割 7 防盗链 三 总结 一 理论
  • 上海交大ACM班C++算法与数据结构——数据结构之栈

    上海交大ACM班C 算法与数据结构 数据结构之栈 1 栈的定义 后进先出LIFO first in last out 先进后出FILO first in last out 的线性表 有关线性表可查看 上海交大ACM班C 算法与数据结构 数据
  • HTML ,CSS ,JS 组合运用制作登录界面,注册界面,相册旋转展示界面,并相互跳转联系,源代码

    完成 个人相册 项目登录页面 要求 1 使用正则表达式验证邮箱 2 密码长度至少为6位且为字母与数字的组合 可自行改变背景图片 此时所用图片与项目在同一目录下 只需写入文件名 图片要在与项目同级目录下 要写入路径及名称 登录界面所有代码如下
  • PHP学习之路——基本语法

    phpinfo是一个函数 功能 这个函数 功能 会显示一个当前电脑 服务器 的详细的PHP信息 我们写完一段代码 就需要在后面加分号 php的代码部份全部要用半角的英文 很多人容易写成全角的英文和符号造成PHP代码报错 PHP中的变量也是如
  • CPU乱序执行

    CPU乱序执行 CPU乱序执行是什么 例程 参考 总结 CPU乱序执行是什么 我们理解的程序是顺序执行的 其实是指在单个独立的进程中表现得像顺序运行的 而多处理器多线程共享内存系统是十分复杂的 需要约束这些复杂系统的行为 我们将程序线程共享
  • mavon-editor 使用及如何将html的数据转为markdown的数据问题

    1 安装mavon editor cnpm install mavon editor s 2 页面使用
  • Python通过smtplib发送邮件

    Python通过smtplib发送邮件 1 邮件发送的步骤 2 邮箱设置 3 发送一封qq邮件 4 发送HTML格式的邮件 5 发送带附件的邮件 6 在HTML文本中添加图片 7 python给同一个人发送多封邮件 8 python给不同的
  • 5.6.2_IEEE754

    文章目录 一 引子 二 移码 1 移码与补码 2 移码本身 1 127 2 3 3 偏置值 普通情况 特殊情况 三 IEEE 754标准 1 格式 2 类型 1 短浮点数 2 double型 3 案例 1 案例一 2 案例二 4 范围 1
  • unity下多层随机迷宫构建

    using System Collections using System Collections Generic using UnityEngine public class Maze MonoBehaviour public GameO