unity 简单实现tilemap的保存和读取(以便用于关卡编辑器)

这篇具有很好参考价值的文章主要介绍了unity 简单实现tilemap的保存和读取(以便用于关卡编辑器)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        最近在学习使用Tiledmap,用于制作地图确实很方便快捷,但总不能一个关卡就做一个prefab?还是必须将其保存为文本文件才行啊,于是有了以下的尝试:  

      先定义一个Tiledmap类,用于存储单个Tiledmap信息

[System.Serializable]
public class SimpleTile
{
    [SerializeField]
    public string name;
    [SerializeField]
    public Dictionary<string, string> tiles = new Dictionary<string, string>();
}

tiles是保存的所有tile块。key为坐标值,value为使用的tilemap的名称。

        然后需要一个管理同一个Grid下所有Tiledmap的类:

[System.Serializable]
public class SimpleGrid
{
    [SerializeField]
    public Dictionary<string, SimpleTile> tiles = new Dictionary<string, SimpleTile>();
}

tiles 的key是tiledMap在Hierarchy中的名称。

之后当然是先保存当前Grid下的所有Tiledmap:

public void SaveLevel()
    {

        Tilemap[] tilemaps = grid.GetComponentsInChildren<Tilemap>();
        SimpleGrid simpleGrid = new SimpleGrid(); 
        for (int i = 0; i < tilemaps.Length; i++)
        {
            //循环读取每一个Tiledmap
            ExportMap(tilemaps[i]);
        }
        Debug.LogWarning(simpleGrid.tiles.Count);
        //将赋值完成的数据转换为json字符串。方便文件存储
        //JsonConvert 是使用的Newtonsoft.Json 的第三方插件,
        //unity自带的JsonUtility可能无法将类正确转换成string。我刚开始就是用的它,发现simpleGrid.tiles.Count一直为0
        mtempJson =  JsonConvert.SerializeObject(simpleGrid);
        
        //获取到字符串,就可以存储到本地啦,关于存储的环节可以使用File类,或者第三方插件完成
        Debug.LogWarning(mtempJson);
    }
    public void ExportMap(Tilemap tilemap)
    {
        //获取到tiledmap的格子信息
        BoundsInt area = tilemap.cellBounds;

        Dictionary<string, string> data = new Dictionary<string, string>();
        simpleGrid.tiles[tilemap.name] = new SimpleTile();
        simpleGrid.tiles[tilemap.name].name = tilemap.name;
        simpleGrid.tiles[tilemap.name].tiles = 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;
                }
                //将已有的tile根据自身坐标存储。
                //之前想直接存储tilemap.cellBounds ,但是在转json时会报错,所以还是这样一个个存吧
                simpleGrid.tiles[tilemap.name].tiles[i+","+j] = tilemap.GetTile(new Vector3Int(i,j,0)).name;
                //---------------这个只是为了测试方便------
                //Tiles存储了地图上用到的瓦片信息。正常使用时应该在初始化时就将其赋值。
                //public Dictionary<string, TileBase> Tiles = new Dictionary<string, TileBase>(); key为瓦片的名称,value为使用的瓦片
                if(!Tiles.ContainsKey(tilemap.GetTile(new Vector3Int(i, j, 0)).name))
                {
                   Tiles[tilemap.GetTile(new Vector3Int(i, j, 0)).name] = tilemap.GetTile(new Vector3Int(i, j, 0));
                }
            }
        }

    }

        之后是读取文件并将其重新绘制到界面。读取文件的方式依旧可以使用File类或者第三方插件,此处不做过多讲解。下面是解析字符串并绘制到界面:

 public void CreateLevel(string json)
    {
        if (json == null)
        {
            Debug.LogWarning("传入字符串为null");
            return;
        }
        //先将json字符串还原为SimpleGrid类
        SimpleGrid simpleGrid = JsonConvert.DeserializeObject<SimpleGrid>(json);
        if (simpleGrid == null)
        {
            Debug.LogWarning("传入的字符串不能正确解析");
            return;
        }
        //先创建一个Grid
        GameObject grid = new GameObject("Grid");
        grid.AddComponent<Grid>();

        Debug.LogWarning("keys::"+simpleGrid.tiles.Count);
        Debug.LogWarning("Tiles::" + Tiles.Count);

        //循环创建每一个Tiledmap,如果想做渐进加载的效果,可以将这个方法修改为协程方式处理
        foreach (var item in simpleGrid.tiles.Keys)
        {
            //创建Tiledmap并将父级设为刚才的Grid
            GameObject tile = new GameObject(item);
            tile.transform.SetParent(grid.transform);
            //添加Tilemap 组件
            Tilemap tilemap = tile.AddComponent<Tilemap>();
            //一定要添加TilemapRenderer组件,之前忘了添加,一直没显示瓦片,还找了半天bug。。。
            tile.AddComponent<TilemapRenderer>();
            //将瓦片信息读取出来
            SimpleTile simpleTile = simpleGrid.tiles[item];
            foreach (var vec2 in simpleTile.tiles.Keys)
            {
                string[] pos = vec2.Split(",");
                //在指定坐标下设置瓦片
                tilemap.SetTile(new Vector3Int(int.Parse(pos[0]), int.Parse(pos[1]), 0), getTile(simpleTile.tiles[vec2]));
            }
        }

    }
    /// <summary>
    /// 根据瓦片名称获取到瓦片的类
    /// </summary>
    /// <param name="tileName"></param>
    /// <returns></returns>
    public TileBase getTile(string tileName)
    {

        TileBase tile;
        //这个Tiles 是刚才在存储时赋值的
        if (Tiles.TryGetValue(tileName, out tile))
        {
            return tile;
        }
        else
        {
            return null;
        }
    }

It‘s Done!!

注::刚才看到有些部分和制作的关卡内容有出入,仔细检查后发现是因为TilemapRenderer的层级没有处理,所以在保存的时候应该保存下TilemapRenderer的SortingLayer和Order in Layer并在创建时赋值。文章来源地址https://www.toymoban.com/news/detail-542501.html

到了这里,关于unity 简单实现tilemap的保存和读取(以便用于关卡编辑器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity记录3.1-地图-TileMap简单使用、鼠标拖动放置Tile

    文章首发及后续更新:https://mwhls.top/4456.html,无图/无目录/格式错误/更多相关请至首发页查看。 新的更新内容请到mwhls.top查看。 欢迎提出任何疑问及批评,非常感谢! 汇总:Unity 记录 上章的课程接下来是巡逻的敌人,不过我地图还没创建好,教程的 AI 估计不适合,所以先

    2024年02月09日
    浏览(14)
  • C++ 实现命令行画心形代码,有多个爱心代码,简单可调数据和字符,可装X,也可用于浪漫的表白,可实现跳动、保存等功能

    C++ 实现命令行画心形代码,有多个爱心代码,简单可调数据和字符,可装X,也可用于浪漫的表白,可实现跳动、保存等功能

    绘制一个简易爱心 绘制一个精致爱心 另一个好的版本 一个最花里胡哨的 绘制红心并保存到文件 绘制跳动的心脏:注此版本只能在Windows系统下编译运行。 升级版 其他做法html 也许我们还可以再做点什么,比如加点动画,看看下面这个吧。 点这里下载源码,里面已经加了很

    2024年02月08日
    浏览(14)
  • Unity 关卡跳转——开始界面切换到游戏场景的实现

    Unity 关卡跳转——开始界面切换到游戏场景的实现

    1 .在已有关卡的基础上,另外新建一个关卡,将其命名为start并进行保存。 2 .在新建立的start关卡中创建TitleScreen.cs脚本,代码如下。 (值得注意的是,这里不要忘记使用unity引擎提供的SceneManagement类,即在脚本顶部添加 using UnityEngine.SceneManagement;) 3 .将TitleScreen.cs脚本挂载到

    2024年02月11日
    浏览(9)
  • 【Unity 3D】C#从JSON文件中读取、解析、保存数据(附源码)

    JSON是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式存储和表示数据,简洁和清晰的层次结构使JSON成为理想的数据交换语言,易于读者阅读和编写,同时也易于机器解析和生成,并有效的提高网络传输效率 生成JSON数据实例代码如下 下面的代码将JSON中数据

    2024年02月11日
    浏览(80)
  • 【实现100个unity游戏之20】制作一个2d开放世界游戏,TileMap+柏林噪声生成随机地图(附源码)

    【实现100个unity游戏之20】制作一个2d开放世界游戏,TileMap+柏林噪声生成随机地图(附源码)

    我的上一篇文章介绍了TileMap的使用,主要是为我这篇做一个铺垫,看过上一篇文章的人,应该已经很好的理解TileMap的使用了,这里我就不需要过多的解释一些繁琐而基础的知识了,省去很多时间。所有没看过上一篇文章的小伙伴我强烈建议先去看看:

    2024年01月20日
    浏览(19)
  • unity存储信息的方式,保存读取背包、游戏进度,连接MySQL数据库

    为了在Unity中存储信息,有几种方法可供选择。最常见的方法是 PlayerPrefs、Serialization和Database 。 PlayerPrefs是一种简单的存储小量数据(如玩家偏好或游戏设置)的方法。它易于使用,不需要任何外部库。但是,不建议用于存储大量数据或敏感信息。 Serialization是另一种在Unit

    2024年02月09日
    浏览(13)
  • OpenCV 实现读取摄像头、视频读取保存 (C++)

    重点语句:VideoCapture、imshow 原理:使用VideoCapture语句读取摄像头,再利用while一次次将VideoCapture所读取的数据利用imshow语句一帧帧地读取出来 重点语句:VideoWriter 原理:在摄像头读取完图之后,利用VideoWriter语句将图像保存为固定格式 通过加入一个循环语句,按空格将图片按

    2024年02月11日
    浏览(10)
  • OpenCV实现视频的读取、显示、保存

    OpenCV实现视频的读取、显示、保存

    目录 1,从文件中读取视频并播放 1.2代码实现 1.3效果展示 2,保存视频 2.1    代码实现 2.2   结果展示 下面将详细介绍如何使用OpenCV实现视频的读取、显示和保存,并解释其原理。 视频读取: 使用OpenCV可以通过 cv2.VideoCapture 类来读取视频文件。该类提供了一系列方法用于操

    2024年02月03日
    浏览(45)
  • Unity核心5——Tilemap

    Unity核心5——Tilemap

    Tilemap 一般称之为瓦片地图或者平铺地图,是 Unity2017 中新增的功能,主要用于快速编辑 2D 游戏中的场景,通过复用资源的形式提升地图多样性 ​ 工作原理就是用一张张的小图排列组合为一张大地图 ​ 它和 SpriteShape 的异同 共同点:他们都是用于制作 2D 游戏的场景或地图的

    2024年02月09日
    浏览(11)
  • Unity 读取外配-第三集-网络下载形式读取外部图片(简单但详细版)

    Unity 读取外配-第三集-网络下载形式读取外部图片(简单但详细版)

    需求:我有一个文件夹,里面有好多好多图片,我想软件自己读出来 一、具体逻辑 1.写出你希望读取的文件夹的地址 2.读取这个文件夹里所有的文件名称 3.把这个文件夹里名称中和图片有关的文件名找出来 4.用代码在unity里创建一个图片 5.用加载的图片替换掉创建的这个图片

    2024年02月12日
    浏览(10)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包