在Unity中简单地制作一张2D地图并随机生成资源

这篇具有很好参考价值的文章主要介绍了在Unity中简单地制作一张2D地图并随机生成资源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这个作业属于哪个课程 软件工程2022年春-F班
这个作业要求在哪里 软件工程实践总结&个人技术博客
这个作业的目标 课程回顾、个人技术总结
其他参考文献 《构建之法》


一、技术概述

1.1 技术使用场景

  你不满足于别人提供的现成的地图,想要利用原有的素材来将你自己的想法实现吗?或者你不知道如何获取素材,不知道如何使用素材?在此发挥你天马行空的想象力,用你的鼠标和键盘来绘制自己的王国吧!

1.2 技术难点

  随机资源生成算法的实现。(注:本人unity版本为2021.3.2f1c1,不同版本可能组件位置有所不同)

二、技术详述

2.1 素材导入

  在项目中,点击左上角菜单栏的window,可以看到子选项中有一个Asset Store。
在Unity中简单地制作一张2D地图并随机生成资源
  点击它我们可以来到Unity资源商店寻找我们想要的资源,包括地图、角色、道具、材质等等,你几乎可以在这里找到所想要的东西。
在Unity中简单地制作一张2D地图并随机生成资源
  点击左上角的2D,并勾选上“环境”、“免费资源”(能不花钱就不花钱啊喂),我们来挑选一张心仪的地图,进入资源详情页后,点击“添加至我的资源”后选择“在unity中打开”即可。
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  选择import,等待资源导入。
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  可以看到左下角的项目文件已经把素材导入进来,现在我们可以开始创作了!
在Unity中简单地制作一张2D地图并随机生成资源

2.2 编辑素材

  首先我们更改一下素材的配置,主要要更改一下素材每单位的像素点。我们可以看到我们的Scene界面有很多网格,一个格子就是一个Unit,这个Pixels Per Unit就是指一个格子中的像素点,当这个值过大,会让每个单位格里面的东西变得很小,个人习惯将这个值调至16,当然你可以自由选择。Sprite Mode更改成Multiple,这会有利于我们后续对素材的切割和制作。更改后,记得点击Apply应用。
在Unity中简单地制作一张2D地图并随机生成资源

2.3 绘制地图

  绘制地图我们需要一个载体,右键左部空白位置,点击2D Object -> Tilemap ->Rectangular ,生成一个Tilemap,供我们在上面制作地图。
在Unity中简单地制作一张2D地图并随机生成资源
  我们还需要一个画板,就跟画家的调色板一样,他们会在上面放上各种颜料,而我们需要在上面放上我们的素材,我们的画板就是Tile Palette。点击左上角的window -> 2D -> Tile Paletee,这时候我们弹出了一个窗口,这个就是我们的画板,将素材(颜料)放在上面,我们才可以进行我们的创作。
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  我们可以看到这个素材包里面有现成的帮我们“调制”好的颜料,不过呢有的素材包是没有的,为了能够掌握地图绘制的步骤,我们来重新“调制”一遍!点击画板中的Create New Palette,将新画板的名字重命名,然后点击Create,这时候会弹窗让我们选择一个保存位置,我们可以新建一个文件夹,随便命名一下(我这里命名为Map),选择该文件夹将该画板保存到这个位置。
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  不过现在你可以看到,我们的画板上没有任何的东西,我们现在需要将我们的素材切割好并导入,也就是调制我们的颜料。在素材详情页面点击Sprite Editor,进入素材编辑界面,点击Type更改切割类型,选择Grid By Cell Size,更改Pixel Size中x和y使之和我们之前定义的Pixels Per Unit数值一致,之后点击slice,最后记得点击右上角的Apply保存。
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  这时我们可以使用素材中每个单元格来进行地图的绘制了!将素材拖入我们的Tile Palette中,选择一个保存的文件夹(我们还是选择放在Map文件夹中),等待导入,之后我们就会发现,我们现在画板上就已经有了素材,而且它已经被划分成了一小格一小格的单位,这时候,我们便可以拿起我们的画笔,正式开始创作!
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  让我们用流程图总结一下简单地图制作的过程!
在Unity中简单地制作一张2D地图并随机生成资源

2.4 关于图层

  图层问题是一个需要长篇幅来叙述的功能,你可以利用图层决定角色、水域、草地等元素的显示优先级以及碰撞等等一些细节的体现,本博客止于地图的简单创建,接下来随机生成物体的内容需要你对诸如Tilemap的创建、预制体的创建等内容有所了解,如果想对这些部分进行学习,可以查看本博客的参考内容中的教程。

2.5 简单的随机资源生成

  我们首先创建一张地图,将可生成资源的地块划分到一个图层,剩下的划分到另一个图层。例如我这里将不可生成资源的地块划分到了unrandomground,可生成资源的地块在randomground中。我们还需要准备一些预制体,将这些预制体作为生成的资源。
在Unity中简单地制作一张2D地图并随机生成资源
  新建一个脚本,开始编写代码。思路如下流程图所示:
在Unity中简单地制作一张2D地图并随机生成资源
  首先做好前期准备,保存我们需要随机的资源:

  //需要随机的资源
    public List<GameObject> resourceGrass = new List<GameObject>(); // 草
    public List<GameObject> resourceGravel = new List<GameObject>(); // 石头
    public List<GameObject> resourceTree = new List<GameObject>(); // 树木、灌木
    public List<GameObject> resourceWoodenConstruction = new List<GameObject>(); // 木制结构
    public List<GameObject> resourceLithicalConstruction = new List<GameObject>(); // 石制结构
    

    private Tilemap tilemap;
    private List<Vector3> randomGroundTileWorldPos = new List<Vector3>(); // 获取可随机的地块
    private bool[] randomGroundTileHasEmptySlot; // 判断地块是否已占用,需要初始化

    private int randomGroundTileCount; // 随机地块数量
    private int resourcesGrassCount; // 草 数量
    private int resourcesGravelCount; // 碎石 数量
    private int resourcesTreeCount; // 树木、灌木
    private int resourcesWoodConstructionCount; // 木制结构数量
    private int resourcesLithicalConstructionCount; // 石制结构数量

  初始化函数,由于我们可以将脚本挂接在randomground下,因此保存所有地块就相当于保存了所有可随机地块:

 void InitializeTileMap() // 保存地图的所有地块
    {
        tilemap = GetComponent<Tilemap>();
        Vector3Int tmOrg = tilemap.origin;
        Vector3Int tmSz = tilemap.size;

        for (int x = tmOrg.x; x < tmSz.x; x++)
        {
            for (int y = tmOrg.y; y < tmSz.y; y++)
            {
                if (tilemap.GetTile(new Vector3Int(x, y, 0)) != null)
                {
                    Vector3 cellToWorldPos = tilemap.GetCellCenterWorld(new Vector3Int(x, y, 0));
                    randomGroundTileWorldPos.Add(cellToWorldPos);
                }
            }
        }
    }

  接着就开始生成资源,这里举例生成草的函数:

  void GenerateGrass(System.Random rm) // 生成草
    {
    	int aRandomTile;
        for (int i = 0; i < 150; i++) 
        {
			while(!randomGroundTileHasEmptySlot[aRandomTile])
            {
              	aRandomTile= rm.Next(0, randomGroundTileCount);
            }
            Vector3 spawnPos = randomGroundTileWorldPos[aRandomTile];
            int aRandomRes = rm.Next(0,resourcesGrassCount);
           	GameObject spawnRes = resourceGrass[aRandomRes];
            Instantiate(spawnRes, spawnPos, Quaternion.identity);
            randomGroundTileHasEmptySlot[aRandomTile] = false;
        }
    }

  编写完代码后,将脚本挂在randomground下,将需要生成的资源以预制体的形式拖入,点击运行,就可以得到我们想要的效果
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  不过我们发现,当物体较多时,生成的速率会变慢,这是因为我们用一个数组去存储地块的生成资源情况会使得在地块稀少时寻找可利用地块耗时增加,我们可以改进一下,将生成过资源的地块直接从我们保存地块的列表之中移出,代码如下:

void GenerateTree(System.Random rm) // 生成树木、灌木
    {
        for (int i = 0; i < 100; i++) // 生成树木和灌木
        {
            randomGroundTileCount = randomGroundTileWorldPos.Count; // 随机地块数量
            int aRandomTile = rm.Next(0, randomGroundTileCount);

            Vector3 spawnPos = randomGroundTileWorldPos[aRandomTile];

            int aRandomRes = rm.Next(0, resourcesTreeCount);
            GameObject spawnRes = resourceTree[aRandomRes];
            Instantiate(spawnRes, spawnPos, Quaternion.identity);

            randomGroundTileWorldPos.Remove(spawnPos);
        }
    }

  可以发现效率较上一种方法高的多。

三、可能遇到的问题以及解决方案

3.1 素材问题

Q:Unity商店里有我很喜欢的素材,但是卖的很贵怎么办?
A:
  如果只是新手练手使用,可以由tb或者pdd等渠道获取,但如果要用于商业,必须由本人在版权方所提供的渠道购买(Unity商店),否则会有侵权的问题。不过Unity商店提供的素材经常有大力度的打折,你可以收藏下你喜欢的素材等打折时购买。这里推荐一个B站Up主Lee哥的游戏开发加油站,他经常发一些优质且有很大折扣的Unity素材,可供参考。

Q:我在切割素材时,有些按Grid By Cell Size类型切割并不能得到我想要的效果?
A:
  可以尝试着选择其他类型的切割方式,或者是调整一下每个单元格的像素量,素材质量有高有低,有时还需要自己微调。

3.2 地图制作问题

Q:我明明给地图某些部分添加了碰撞体积,但是子弹能穿过去?
A:
  地图的碰撞体积一般由如下图三部分构成,选择Composite Collider 2D中的Geometry Type(指定复合碰撞体生成的几何体的类型),将其设为Polygons(设置符合碰撞体,以便为由凸多边形组成的合并碰撞体集合体生成封闭轮廓),然后在子弹的碰撞体积中,设置Rigidbody 2D的Collision Detection为Continuous(连续检测,防止对象穿过所有静态碰撞体)
在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源
  可参考Unity-Rigidbody组件、Unity官方文档-GeometryType。

3.3 随机生成资源问题

Q:生成的物体位置与我设想的不一致?
   正常情况下树木如果在它脚下这块石板上生成,应该会是如下图所示,但实际会往下偏移
在Unity中简单地制作一张2D地图并随机生成资源
A: 这是预制体的锚点问题,在sprite Editor中将对应物体的锚点往下移动即可。
在Unity中简单地制作一张2D地图并随机生成资源
Q:生成的物体图层有问题,例如树木后面的物体应该是被遮蔽的,事实却不是如此?
A:
  点击Edit选择ProjectSettings,在Graphics中选择Transparency Sort Mode,将其置为Custom Axis,此时在同一图层上,物体会根据所处的Y值排序,即Y值越高,显示优先级越靠后,便解决了该问题

在Unity中简单地制作一张2D地图并随机生成资源
在Unity中简单地制作一张2D地图并随机生成资源

四、总结

  Unity的地图制作是新手入门Unity的必学操作之一,其难度并不高,主要依靠学者的细心和耐心。关于资源的随机生成本博客只是提供了一个简单的办法,实际上关于随机地图的生成有其他更深入的研究,包括限制资源生成范围、地形的生成,甚至可以做到地图全随机而不用自己先搭建出一个框架,涉及到了各种模型分析和数值计算。学无止境,不可止步于此。

五、参考内容

1、如何在Tilemap上随机生成资源——bilibili
2、Unity2018教程2D入门——bilibili
3、Unity官方用户手册文章来源地址https://www.toymoban.com/news/detail-401436.html

到了这里,关于在Unity中简单地制作一张2D地图并随机生成资源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零开始入门创作游戏——2D沙盘类随机地图的生成

    如果想做类似于泰拉瑞亚的沙盘游戏,首先需要生成随机的地图。 首先需要确定地图大小和砖块元素 1、地图所需基本参数 因为只有第一次开始时会生成地图,所以可以删除update函数 2、砖块元素 为了简单,直接创建方块元素来代替游戏砖块。在资源栏右键创建即可。默认白

    2024年02月05日
    浏览(42)
  • 【简单详细】Unity生成地形和UI小地图实时展示人物位置的详细制作过程

    效果: 注意:一个 父物体 Map是一个纯白色image,放到左上角,要加 Mask组件 哦!!!       它的 两个子物体, 其中一个(map)是显示出地图纹理的image,另外一个(mapPlayer)是一个小点,我们也用image来表示,也就是效果图上的 绿点 。     我们把人物放进去,挂载脚本

    2024年02月05日
    浏览(49)
  • Unity 关于制作一个2D的小地图

    实际效果:   需求:1.实现右上角小地图,实现同步本地地图           2.实现小地图内的角色图标和实际角色同步 实现原理: 1.在所需要的地图上划分为一下结构 图层Tilemap6_Minimap的Layer为Minimap 同时这里说一个问题,在同层级的图片,序列越晚渲染越上层 2.使用另一个摄像

    2024年02月14日
    浏览(43)
  • unity2d实现一个全方位的无限随机地图

    要实现一个全方位的无限随机地图,可以考虑以下步骤: 1.创建一个空的场景,并添加一个相机和一个玩家对象。 2.创建一个TileMap,它将作为你的地图板块。你可以使用随机数生成算法生成各种类型的地形,如森林、草地、沙漠等等,并使用TileMap将它们组装在一起来创建你

    2024年02月07日
    浏览(44)
  • unity如何制作随机生成器

    随机生成器的制作至少应具备四个个要素:需要随机生成的物体、物体随机生成的间隔时间、每生成一次的物体个数、一定时间后销毁物体。 其中最关键的问题是如何间隔一定时间生成,这里提供两种思路:1.运用协程。2.做个计时器。 在这里我们需要初步了解一下协程。

    2023年04月09日
    浏览(58)
  • 【unity实战】随机地下城生成2——绘制地图Tilemap的使用及一些技巧的使用(含源码)

    参考原视频链接: 【视频】:https://space.bilibili.com/370283072 注意 :本文为学习笔记记录,推荐支持原作者,去看原视频自己手敲代码理解更加深入 修改素材配置 切割图片 绘制瓦片地图 先新建我们的调色盘,保存好位置 拖入我们刚才切片好的素材 在房间预设体创建我们的瓦

    2024年02月13日
    浏览(44)
  • 13.Unity2D 横版 可上下左右移动的双向平台(双向行走+可移动+单独判定)+随机平台生成

        总目录 https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 大多数平台教程全是碰撞体的可移动平台,并没有可跳上的平台,并且要求按下键会从平台上跳下来。有也只是通过控制平台的“2D平台效果碰撞体”组件的单向平台的旋转偏移来做,但是这样会 出现一

    2024年02月04日
    浏览(53)
  • 10.Unity2D 横版 简单AI 之 敌人随机移动+自动巡逻+障碍物跳跃+悬崖处转身+射线检测

    总目录 9.Unity2D 简单AI 之 敌人跳跃条件优化+自动范围内检测敌人发起攻击(索敌)+对象池优化+主角受伤死亡_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客 Unity2D 简单AI 之 敌人跳跃条件优化+自动范围内检测敌人攻击+敌人二连击。在敌人预制体下,创建空物体EnemyCanAttack,改成不

    2023年04月20日
    浏览(51)
  • 【Live2d】一张图制作Live2d基本脸捕动画(下)

    上一篇讲了CubismEditor(CE)的基本操作和动画设置,接下来就是正式的脸捕设置的创作了 由于立绘是睁开眼的,如果需要让他闭眼,需要自己手绘2个眼睑,一个上眼睑,一个下眼睑 (如果是自己的OC那就叫画师帮忙画一下和记得分层)  我这种图像由于眼睛附近的颜色都是一

    2024年02月03日
    浏览(42)
  • 利用envi与arcmap/arcgisPro制作一张植被覆盖指数专题地图(地图学作业)

    本篇文章是作者的第一篇文章,对于软件的使用和对专业知识的了解都很浅薄,作为遥感专业的入门级玩家,我认为发布一篇博客来记录自己的学习过程与成果是很有必要的,一是可以重新梳理完成学习任务的基本思路,二是总结完成这次任务中自己的收获并巩固提高,三是

    2023年04月25日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包