百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Unity3D引擎 2D地图TileMap 存档 保存地图

cac55 2024-11-15 16:39 26 浏览 0 评论

关注公众号,获取更多干货。

下面是正文:

最近在恶补Unity的一些模块,前几天朋友推荐我看一下Unity2017.2以上才支持的TileMap,他说用这个做2D关卡贼方便,所以我就去看了一眼,的确很棒,包括官方出的Demo也是看一眼基本上就能学会,所以说到这里不得不骄傲一下,Unity现在是越做越牛x,身为Unity的攻城狮我真是感到无比的咳咳咳咳咳…

好了废话不能多说,先说说我为啥要写这篇博客,其实TileMap这个工具是真的很好用,但是有一个问题,一般需要设计2D关卡的游戏,都是需要很多关的,就连给我介绍这个TileMap的朋友都说,他现在在做的游戏才刚刚200关,嗯?才200关?才?

那么问题来了,这个地图是怎么保存的呢,200个Scene?还是做了200个预制体?不过这个我倒是没有问,然后我百度了一下TileMap保存地图,还真没有人写过类似保存TileMap地图、载入TileMap地图的,那索性我就来搞一下吧,虽然这只是第一个版本,但是还是欢迎大家和我一起完善,写的不好的地方请见谅哈。

其实到了这里,不妨会有人问我,这玩意有啥用,其实说没用真没啥用,要说有用的话还特别的有用,就是你把这些东西都弄完,然后让你们的策划学会咋用这个工具,关卡搭建的事情交给ta就好了,一劳永逸。

而且如果你的地形地图需要放在服务器动态加载的话,这个功能就不错啦。

为了防止有人还没用过或者还不是很熟悉TileMap,这里我就贴一个链接,大家可以通过这个前辈的博客,来学习或了解一下TileMap。

通灵召唤术:https://www.jianshu.com/p/d8fe795bf6c7


如果上面那个文章大家都吃透了的话,我就开始讲解我的逻辑啦。

0x00) 导出\保存 地图

class 0x00_1{
	画笔\瓦片 也就是 Tile 我暂时把他定为两大类,Rule Tile 和 Default Tile;
	Rule Tile 就是导入插件后的可自定义的高级画笔,Defaule Tile就是默认的画笔;
	我们需要把这两种画笔区分开来,通过Unity编辑器拖拽,让我的脚本识别你的所有Tile;
	手动编辑Init();
	初始化所有Tile,并将Tile添加到Dictionary中方便后期载入地图使用。
}
class 0x00_2{
	在每一层TileMap上挂载一个ReadTilemap脚本,用来读取地图和保存地图;
}

0x01) 导入\载入 地图

class 0x01_1{
	通过Unity编辑器拖拽,让我的脚本识别所有需要载入地图的TileMap;
}	
class 0x01_2{
	通过TileMap名称,找到对应的地图文件,开始载入地图;
}

0x02) ReadTilemap.cs脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class ReadTilemap : MonoBehaviour
{
 /// <summary>
 /// Maps to be saved
 /// </summary>
 private Tilemap tilemap;
 /// <summary>
 /// The boundaries of the map need to be preserved
 /// </summary>
 public BoundsInt area;
 // Start is called before the first frame update
 void Start()
 {
 tilemap = GetComponent<Tilemap>();
 }
 void Update()
 {
 if(Input.GetKeyDown(KeyCode.S))
 {
 ExportMap();
 }
 if (Input.GetKeyDown(KeyCode.C))
 {
 ClearMap();
 }
 }
 public void ExportMap()
 {
 TileBase[] tileArray = tilemap.GetTilesBlock(area);
 print(tilemap.name + " - Area size: " + tileArray.Length);
 int tilecount = 0;
 Dictionary<string, string> data = new Dictionary<string, string>();
 for (int i = area.xMin; i < area.xMax; i++)
 {
 for (int j = area.yMin; j < area.yMax; j++)
 {
 if (tilemap.GetTile(new Vector3Int(i, j, 0)) == null)
 {
 continue;
 }
 print(tilemap.GetTile(new Vector3Int(i, j, 0)).ToString());
 Vector3Int temp = new Vector3Int(i, j, 0);
 data.Add(i + "," + j, tilemap.GetTile(temp).name);
 tilecount++;
 }
 }
 string jsonData = LitJson.JsonMapper.ToJson(data);
 MapsMode._Instance.ExportMap(jsonData, tilemap.name);
 print(tilemap.name + " - The number of tiles in the area : " + tilecount);
 }
 public void ClearMap()
 {
 tilemap.ClearAllTiles();
 }
}

0x03) ReadTilemap.cs脚本使用讲解

class 0x03_1{
	每一个需要保存地图的TileMap都要挂载这个脚本;
	保存地图是会保存多个文件,每个TileMap会保存成一个文件;
}	
class 0x03_2{
	文件路径是Application.dataPath + "/Maps/" + Maps[i].name + ".txt";
	也就是你的Assets路径下的Maps文件夹;
	地图文件的名字就是TileMap的GameObject名字加上.txt;
}	
class 0x03_3{
	这个脚本使用的时候有一个需要注意的地方;
	public BoundsInt area;
	这个值需要手动输入;
	我先将一下这个是干啥用的,其实很简单,这个就是TileMap的边界;
	我是根据这个边界来遍历里面的所有Tile;
}
class 0x03_4{
	area边界的值可以用TileMap给到工具去测量;
}

0x04) MapsMode.cs脚本

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Tilemaps;
public class MapsMode : MonoBehaviour
{
 public static MapsMode _Instance;
 void Awake()
 {
 if (_Instance == null)
 {
 _Instance = this;
 }
 }
 /// <summary>
 /// Rule Tile
 /// </summary>
 public TileBase GrassPlatform;
 public TileBase Waterfall;
 /// <summary>
 /// Default Tile
 /// </summary>
 public TileBase[] EnvironmentProps;
 /// <summary>
 /// All Tile
 /// </summary>
 public Dictionary<string, TileBase> Tiles = new Dictionary<string, TileBase>();
 /// <summary>
 /// All Tile Map
 /// </summary>
 public Tilemap[] Maps;
 void Start()
 {
 Init();
 }
 public void Init()
 {
 Tiles.Add("GrassPlatform-RuleTile", GrassPlatform);
 Tiles.Add("Waterfall-RuleTile", Waterfall);
 for (int i = 0; i < EnvironmentProps.Length; i++)
 {
 Tiles.Add("EnvironmentProps_TileSet_" + i, EnvironmentProps[i]);
 }
 print("Init() is over.");
 }
 void Update()
 {
 if (Input.GetKeyDown(KeyCode.I))
 {
 ImportMap();
 }
 }
 public void ImportMap()
 {
 for (int i = 0; i < Maps.Length; i++)
 {
 FileInfo fi = new FileInfo(Application.dataPath + "/Maps/" + Maps[i].name + ".txt");
 if (fi.Exists)
 {
 StreamReader sr = fi.OpenText();
 string data = sr.ReadToEnd();
 print("ReadData ===> " + data);
 Dictionary<string, string> mapData = LitJson.JsonMapper.ToObject<Dictionary<string, string>>(data) as Dictionary<string, string>;
 foreach (KeyValuePair<string, string> kvp in mapData)
 {
 string dataKey = kvp.Key;
 string dataValue = kvp.Value;
 string[] posData = dataKey.Split(',');
 Vector3Int pos = new Vector3Int(int.Parse(posData[0]), int.Parse(posData[1]), 0);
 TileBase tileData = getTile(dataValue);
 Maps[i].SetTile(pos, tileData);
 print("Create Tile ===> " + pos + " : " + tileData);
 }
 sr.Close();
 sr.Dispose();
 }
 else
 {
 print("ERROR !!! ===> File Not Found.");
 }
 }
 }
 public void ExportMap(string data, string mapName)
 {
 string filePath = Application.dataPath + "/Maps/" + mapName + ".txt";
 print("FilePath: " + Application.dataPath + "/Maps/" + mapName + ".txt");
 FileInfo fi = new FileInfo(filePath);
 if (fi.Exists)
 {
 print("File is Exists,Delete!");
 fi.Delete();
 fi.Refresh();
 }
 StreamWriter sw = fi.CreateText();
 sw.Write(data);
 sw.Flush();
 sw.Close();
 sw.Dispose();
 fi.Refresh();
 }
 public TileBase getTile(string tileName)
 {
 TileBase tile;
 if (Tiles.TryGetValue(tileName,out tile))
 {
 return tile;
 }
 else
 {
 return null;
 }
 }
}

0x05) MapsMode.cs脚本使用讲解

class 0x05_1{
	首选根据不同要求,要将项目中使用到的所有Tile都添加到这个脚本的记录当中;
	Rule TIle 与 默认的 Tile 要区分记录;
	通过Unity拖拽添加后,在Init()函数中初始化,将所有Tile都添加到同一字典中方便查找;
	Rule Tile比较好添加,但是默认的Tile有很多的瓦片,下面教大家一个简便的方法;
}	

class 0x05_2{
	导入Tile后需要手动编辑Init()函数;
	Rule Tile直接Add就OK;
	由于默认的Tile是数组,所以需要循环遍历Add;
}	
class 0x05_3{
	让脚本识别场景中所有的TileMap同0x05_1拖拽即可;
}	

0x06) 测试

class 0x06{
	运行项目,在控制台打印Init() is over.后即可测试;
	按下“S”即可保存地图 - Save;
	按下“C”即可清空地图 - Clear;
	按下“I”即可载入地图 - Import;
}	

0x07) 新建地形运行保存,删除部分地形在运行,先删除所有后再加载

0x08) 加载时添加延时效果


好啦,以上就是我的全部代码啦,这次就不贴工程文件了,毕竟写的不是可以应用到实际项目的,还有好多东西需要扩展。

例如Editor编辑扩展、动态加载Tile、动态加载Tilemap、保存的地图问价加密、加载地图文件时解密

再或者可以做成那种在服务器后台加载地图等等,欢迎大家一起与我共同扩展这个小功能吧。

最后,感谢大家的阅读~

————————————————

版权声明:本文为CSDN博主「Aries.H」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Aries_H/article/details/101760141

相关推荐

正点原子开拓者FPGA开发板资料连载第四十章 SD卡图片显示实验

1)实验平台:正点原子开拓者FPGA开发板2)摘自《开拓者FPGA开发指南》关注官方微信号公众号,获取更多资料:正点原子3)全套实验源码+手册+视频下载地址:http://www.openedv.c...

东芝存储改名为铠侠了,铠侠microSD卡128GB全网首测

作为一个数码爱好者,平时总爱把玩各种科技数码产品,最近又迷上了口袋云台相机,大疆OsmoPocket、飞宇口袋相机、SnoppaVmate口袋相机什么的,不过这类产品由于设计的机身体积很小(毕竟为...

SD存储卡卡面上奇奇怪怪的图标,你知道几个?

现在对高像素照片、连拍、4K甚至8K的需求越来越多,对存储卡的传输速度、容量等,要求也越来越多了。但是,看到SD存储卡卡面上奇奇怪怪的图标,让人非常迷惑。这篇文章让你简单认识这些图标和奇奇怪怪的数字。...

拍摄4K视频上选!铠侠 EXCERIA PLUS microSD卡

大家好,我是波导终结者。今天跟大家分享的是铠侠的EXCERIAPLUS极至光速microSDXCUHS-1存储卡,名字有点长,但是不用担心,我会帮大家梳理好存储卡的选购建议。有不少刚入门的朋友...

高速稳定,一卡多用:铠侠极至光速microSD存储卡评测

Hello,大家好,我是小胖子。半个月前收到了KIOXIA铠侠寄来的一张256GB的TF卡,用了大半个月,让我们看看这款产品表现如何吧。其实很多人并不太了解铠侠,问我铠侠是什么品牌,好不好。其实,东芝...

读速205MB/s、V30规格,雷克沙SILVER系列存储卡再添新成员

IT之家6月19日消息,雷克沙今日推出3款SILVER系列SD/microSD存储卡新品,支持4K60fps录像。据介绍,该系列存储卡均符合V30标准,其中micr...

相机、无人机拍视频,选择SD存储卡有什么需要知道的?

本文章不涉及产品推荐导购行为,致力于给到小白带来基础知识。相机一般使用SD卡,无人机一般使用microSD卡(也叫TF卡),使用的标准和图标标识是一样的。相机、无人机拍视频,选择SD存储卡有什么需要知...

PNY推出适用Switch 2的microSD Express卡,读取速度高达890MB/s

任天堂Switch2开始预订,其比前代产品变得更加昂贵,各种配件的价格都高于预期,这也包括转向microSDExpress存储。此时,PNY推出了新款microSDExpress闪存卡。新款mi...

SD卡迎来25周年:全球售出120亿张,容量翻50万倍

IT之家5月21日消息,科技媒体betanews今天(5月21日)发布博文,报道称SD卡迎来了25周年的生日。自2000年首款SD存储卡问世以来,已走过25个年头...

微单相机买一款什么样的SD卡才够用?写入速度更为关键

最近,评价君朋友发现自己的卡拍摄视频时候总断流,于是感觉写入速度应该是不够的,打算换卡,评价君正好跟他说道说道。目前的SD存储卡,很多只标注读取速度,比如95MB/s,80MB/s等等,而没有写写入速...

金士顿Canvas Go!Plus 系列存储卡评测

前言2020年,金士顿推出了CanvasGo!Plus系列存储卡,凭借其优秀的读写速度和稳定性获得了广大用户的认可。时隔5年,金士顿推出了其全新升级产品:SDG4/SDCG4,可选容量覆盖64GB...

TF卡速度等级|MK米客方德(tf卡速度等级图)

TF卡(TransFlash卡,又称MicroSD卡)是一种常见的便携式存储媒体,广泛用于智能手机、相机、平板电脑等设备中。TF卡的性能通常由速度等级来衡量,这些等级反映了TF卡的数据传输速度。拓优星...

关于SD卡,看这张表就够了(sd卡的作用)

这里是溢图科技(原“相机笔记”)。这两天有不少存储产品促销,随之而来的就是关于SD卡的一些提问。文章以前已经写过很多了,这里主要给大家看一张表格:上面就是SD卡协会官方制作的“族谱”,明确给出了不同版...

轻量化储存的首选——凯侠极致光速256G microSD存储卡实测

对于摄影师而言,我们经常会接触到相关存储设备,像照片拍摄中给相机安装的SD卡,视频录制中外录高规格画面的SSD等,都属于专业的存储介质,被应用于商业拍摄、电影级别拍摄之中。而针对生活中我们日常用于拍摄...

首发1569元,读取速度可达250MB/s,闪迪推出最新2TB至尊超极速存储卡

近日,闪迪(SanDisk)正式发布了其最新的2TB至尊超极速microSDXCUHS-I存储卡。据悉,这款存储卡的读取速度可达250MB/s,写入速度则达到150MB/s。这意味着用户在处理高分辨...

取消回复欢迎 发表评论: