当前位置:   article > 正文

12.Unity2D 横版 TileMap随机生成简易横版瓦片地图+随机生成环境(花草树石)精灵图+2d-extras+协程的应用_unity2d随机地图

unity2d随机地图

量过大

 总目录

本教程涉及协程,如果不懂协程请点击上方总目录6,7节课查看协程

 为什么要用携程呢?因为协程可以使得整个函数在过程运行,而不用一帧中完成所有的函数,不然只得计算量过大,让机器卡住。

 开始

        我所查到的教程几乎全是伪3DRPG类型的随机地图生成,大多数通过噪声和通路算法完成,但我们的目标是横版类型的地图,不能在那样生成含高度的岛屿形状,就如同泰拉瑞亚游戏的那种,并放大一些冒险跑酷要素会更好。

1.基础TileMap教程

首先在层级目录下,右键->2D对象->瓦片地图,会新建Grid物体自带一个Tilemap子物体

注意使用复合碰撞器 composite collider 2D可以压缩优化瓦片碰撞盒,将连接在一起的瓦片碰撞盒视为一个整体

 

Unity TileMap工具教程_我寄人间雪满头丶的博客-CSDN博客_tilemap unity1.介绍TileMap是Unity的一个插件,可以很方便的进行2D游戏地编,可能是由于功能便捷现在新版的Unity已经集成该插件,不需要再额外导入。2.准备要注意的是素材尺寸需要使用8x8倍数的,不然无法使用。3.使用这次学习使用的素材是在资源商店下载的,名字叫Sunny Land。在Project目录下找到我们需要用到的素材。接下来对素材进行处理。因为我们要切割该素材,所以需要将SpriteMode改为Multiple。素材每个格子尺寸为16,PixelsPerUnit改为16。然后选择https://blog.csdn.net/qq_39162826/article/details/112144150?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-112144150-blog-114226314.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-112144150-blog-114226314.pc_relevant_vip_default&utm_relevant_index=12.2d-extras基础知识

 

为什么要用这个插件?因为这个插件可以自动的根据你生成生成对应不同的瓦片地图(即规则瓦片Rule Tile),让减少了我们来进行判断这个地图是在边缘还是内部的算法,他也可以做到随机生成预制体之类的,很多功能。咱们只用到这两个功能就行。

(1)下载和导入

Unity个人笔记(一):用Tilemap绘制2D地图_smillingman的博客-CSDN博客_切割tilemap  在寒假期间,学了一些unity2D皮毛,找一些重要的整理一下。我个人的项目是类似于宝可梦式的回合制战斗冒险类,并非2D横版游戏。所以代码与2D横版游戏有些许不同。  Unity版本为2019.4.20f1c1(兴趣使然,半路出家。代码混乱,逻辑不通。大佬轻喷)一、利用Tilemap构建地图(包含Rule Tile的使用)  一个游戏最为基础的是关于游戏场景的搭建。unity吸收了RPGMaker的传统功能,也就是利用瓦片来构建地图。Tilemap本身其实没什么好讲的,就简单讲几点。1、素材选择https://blog.csdn.net/smillingman/article/details/114226314?spm=1001.2014.3001.5506当打开调色板的笔刷发现不止一种的时候就是导入成功了!

---如何创建平铺调色板

 ---如何创建规则瓦片

 我自己创建的部分规则,中间灰色为你右边导入的精灵sprite图位置,绿色(点一次)为可连接此处的方块,红色(点俩次)为没有方块

 将规则瓦片拖入到自己创建的平铺调色板上,就可以画了。会根据瓦片周围的情况自己变。

 (3)常用API介绍

Unity-瓦片地图详解_卖烤麸烤饼儿的博客-CSDN博客_瓦片地图前言在学习瓦片地图的使用时,我发现无论国内外还是Unity官方的相关教程都比较散,接触的比较浅,学的我挺难受的,所以就把各个地方看的教程加上我自己的理解,和官方的API手册,总结出了这个详解。0. 瓦片地图基础知识0.1 什么是瓦片地图TileMap是Unity5.5a实验版加入的新功能,就像他的字面意思「瓦片地图」。但说起来这个技术并不“新”了,成熟的2D引擎(诸如gamemaker,RpgMaker),都带有自己自己的tile编辑器的,第三方的编辑工具如Tiled使用起来也是比较方便的,Tilhttps://blog.csdn.net/qq_44705559/article/details/120836932?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165776691616781435470712%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165776691616781435470712&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-120836932-null-null.142%5Ev32%5Edown_rank,185%5Ev2%5Etag_show&utm_term=Unity%E7%93%A6%E7%89%87%E5%9C%B0%E5%9B%BE%E8%AF%A6%E8%A7%A3&spm=1018.2226.3001.4187

3.横版随机地图生成

思路就是先生成瓦片,再进行创建能通过的通道。

生成瓦片的时候先随机生成瓦片起始点,再通过一个协程从瓦片起始点开始延长不等长度(因为是横版游戏,在横向上的延伸要求高)

 首先创建TileMapManager空物体,在空物体下面加入脚本GroundTIleMap

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Tilemaps;
  5. public class GroundTIleMap : MonoBehaviour
  6. {
  7. public Tilemap tilemap;//拖动获取瓦片地图
  8. public TileBase groundTile;//拖动获取地面规则瓦片Rule Tile,-
  9. public Vector2Int lowerLeftCoo = new Vector2Int(-18, -7);//地图左下角位置
  10. public int width= 20;//地图宽度
  11. public int length= 100;//地图长度
  12. // Start is called before the first frame update
  13. void Start()
  14. {
  15. StartCoroutine(GroundStartPoi());
  16. }
  17. // Update is called once per frame
  18. IEnumerator GroundStartPoi()//生成地面起始点 用协程可以缓慢一步步生成地图,性能消耗少
  19. {
  20. tilemap.ClearAllTiles();
  21. Debug.Log("开始生成地面");
  22. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  23. {
  24. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y); j++)
  25. {
  26. yield return null;
  27. bool IsGround = j< (this.width +3)?(Random.value > 0.9): (Random.value > 0.95);//三元表达式,地面三行更容易生成地面起始点
  28. if (IsGround) StartCoroutine(GroundExtension(i,j));
  29. }
  30. }
  31. Debug.Log("结束生成地面");
  32. StartCoroutine(ClearChannel());//执行完GroundStartPoi(),GroundExtension()生成地面,开始清除产生能走的通道
  33. }
  34. IEnumerator GroundExtension(int i,int j)//从地面起始点开始延长
  35. {
  36. int groundLen = Random.Range(2, 10);
  37. for (int m = i; m <= i + groundLen; m++)
  38. {
  39. yield return null;
  40. tilemap.SetTile(new Vector3Int(m,j,0),groundTile);
  41. }
  42. }
  43. //清除,产生通道,思路就是从底层有方块的地方,开始判断上面。如果没有方块的话,就清除俩层/三层的通道
  44. IEnumerator ClearChannel(){
  45. Debug.Log("开始产生通道");
  46. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  47. {
  48. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y-1); j++)//最高层上面必然没有方块,不需要判断,-1
  49. {
  50. if (tilemap.GetTile(new Vector3Int(i, j, 0)) != null)//如果此处不为空方块
  51. {
  52. if (tilemap.GetTile(new Vector3Int(i, j + 1, 0)) == null)//如果此处上方为空方块
  53. {
  54. tilemap.SetTilesBlock(new BoundsInt(i-2, j + 1, 0,3,3,1),new TileBase[] { null,null, null, null, null, null,null, null, null });//将上方3x3格子置空
  55. }
  56. }
  57. yield return null;
  58. }
  59. }
  60. }
  61. }

4.Random Tile随机瓦片生成花,草,石头

和规则瓦片的创造方式一样,先创建tileMap,再创建ruleTile

注意需要修改环境瓦片地图的平铺轴和精灵图片的锚点位置,确保随机生成的精灵图是接触与地面而不是悬空的。(由于随机生成的环境精灵图大小不一样,但锚点都在中间,所以需要修改锚点)

 

提取常数,设置成可以改变的变量,再加上环境步骤脚本更新:

 

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Tilemaps;
  5. public class GroundTIleMap : MonoBehaviour
  6. {
  7. public Tilemap ground_tilemap;//拖动获取地面瓦片地图
  8. public Tilemap environ_tilemap;
  9. public TileBase groundTile;//拖动获取地面规则瓦片Rule Tile,-
  10. public TileBase environTile;//拖动获取环境规则瓦片
  11. public Vector2Int lowerLeftCoo = new Vector2Int(-18, -7);//地图起始左下角位置
  12. public int width= 20;//地图宽度
  13. public int length= 100;//地图长度
  14. public float groundStartPro = 0.10f;//生成地面起始点的概率
  15. public Vector2Int groundLenRan = new Vector2Int(3, 10);//起始地面点生成的长度范围
  16. public float environmentRich = 0.5f;//环境丰富度
  17. // Start is called before the first frame update
  18. void Start()
  19. {
  20. StartCoroutine(GroundStartPoi());
  21. }
  22. // Update is called once per frame
  23. IEnumerator GroundStartPoi()//生成地面起始点 用协程可以缓慢一步步生成地图,性能消耗少
  24. {
  25. ground_tilemap.ClearAllTiles();
  26. Debug.Log("开始生成地面");
  27. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  28. {
  29. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y); j++)
  30. {
  31. yield return null;
  32. bool IsGround = j< (this.width +3)?(Random.value <= groundStartPro) : (Random.value <= groundStartPro+0.05);//三元表达式,地面三行更容易生成地面起始点
  33. if (IsGround) StartCoroutine(GroundExtension(i,j));
  34. }
  35. }
  36. Debug.Log("结束生成地面");
  37. StartCoroutine(ClearChannel());//执行完GroundStartPoi(),GroundExtension()生成地面,开始清除产生能走的通道
  38. }
  39. IEnumerator GroundExtension(int i,int j)//从地面起始点开始延长
  40. {
  41. int groundLen = Random.Range(groundLenRan.x, groundLenRan.y);
  42. for (int m = i; m <= i + groundLen; m++)
  43. {
  44. yield return null;
  45. ground_tilemap.SetTile(new Vector3Int(m,j,0),groundTile);
  46. }
  47. }
  48. //清除,产生通道,思路就是从底层有方块的地方,开始判断上面。如果没有方块的话,就清除俩层/三层的通道
  49. IEnumerator ClearChannel(){
  50. Debug.Log("开始产生通道");
  51. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  52. {
  53. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y-1); j++)//最高层上面必然没有方块,不需要判断,-1
  54. {
  55. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) != null)//如果此处不为空方块
  56. {
  57. if (ground_tilemap.GetTile(new Vector3Int(i, j + 1, 0)) == null)//如果此处上方为空方块
  58. {
  59. ground_tilemap.SetTilesBlock(new BoundsInt(i-2, j + 1, 0,3,3,1),new TileBase[] { null,null, null, null, null, null,null, null, null });//将上方3x3格子置空
  60. }
  61. }
  62. yield return null;
  63. }
  64. }
  65. Debug.Log("产生通道完成");
  66. StartCoroutine(GenerateEnviron());
  67. }
  68. IEnumerator GenerateEnviron()
  69. {
  70. Debug.Log("开始生成花草");
  71. yield return null;
  72. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  73. {
  74. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y ); j++)
  75. {
  76. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) ==groundTile&& ground_tilemap.GetTile(new Vector3Int(i, j+1, 0)) == null)//如果此处为地面,上面为空方块
  77. {
  78. if (Random.value < environmentRich)//随机
  79. { environ_tilemap.SetTile(new Vector3Int(i, j + 1, 0), environTile); }
  80. }
  81. yield return null;
  82. }
  83. }
  84. }
  85. }

 完成了!!!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号