Unity记录4.3-存储-点击Tilemap保存或读取区块
文章首发见博客:https://mwhls.top/4816.html。
无图/格式错误/后续更新请见首发页。
更多更新请到mwhls.top查看
欢迎留言提问或批评建议,私信不回。
汇总:Unity 记录
摘要:点击tilemap,文件 保存/读取 该地图区块数据。
思路-2023/08/17
- 保存和读取上,都很土,都是两层循环,暂时没找到可以批量处理的。
- 如果大家有更好的方式欢迎留言,我找到更好的方式之后也会在这里更新。
- 分块:地图被分为若干块,每块大小一样,以避免大地图长时间加载。
- 存储形式:地图暂时以二维数组保存,二维数组的xy即地图块内的xy,值为tile ID(见上篇Sec. 4.2)。
- 保存:Tilemap中,
tile.name
为tile的文件名,因此tilemap保存为ID数组时,需要将tile转name,在从name转ID。 - 读取:与保存相反,ID需要转为tile,因此一个额外的
ID2tileName
字典被设计,即ID转name转tile。 - Tile保存:在读取中,一个10x10的block会循环100次,其中包含诸多重复Tile。在上篇中,Tile通过文件读取。为减少IO操作,Tile文件在被首次读取时,会被记录,因此一个
name2tile
字典被设计。
数据结构-2023/08/16
public struct TileInfo{public string ID;public string name;public string description;public string path;};public struct TilesInfo{public string version;public string date;public Dictionary<string, TileInfo> tiles;}public struct TilemapInfo{public int[] block_offset;public List<List<string>> map;}private static TilesInfo tilemap_info;private Dictionary<string, TileBase> name2tile;private Dictionary<string, string> ID2tileName;public Vector3Int block_size;
初始化相关-2023/08/16
- 加载上篇的
TilesInfo
,即名字转路径,用于从本地读取tile。
void load_tiles_info(){// load configstring tiles_info_path = "Assets/Resources/Saved/TilesInfo.json";string jsonText = File.ReadAllText(tiles_info_path);tilemap_info = JsonConvert.DeserializeObject<TilesInfo>(jsonText);// initname2tile = new Dictionary<string, TileBase>();ID2tileName = new Dictionary<string, string>();// init ID2tileNameID2tileName.Add("0", "");foreach (var tile_kv in tilemap_info.tiles){ID2tileName.Add(tile_kv.Value.ID, tile_kv.Key);}}
转换函数-2023/08/16
- tile名为空,ID为"0"时表示无tile。
public TileBase map_name_to_tile(string name){if (name == ""){// No tilereturn null;}if (name2tile.ContainsKey(name)){// Tile have been loadedreturn name2tile[name];}else{// Load tilestring tile_path = tilemap_info.tiles[name].path;TileBase tile = Resources.Load<TileBase>(tile_path);name2tile.Add(name, tile);return tile;}}public TileBase map_ID_to_tile(string ID){return map_name_to_tile(ID2tileName[ID]);}public string map_tile_to_ID(TileBase tile){if (tile == null){return "0";}else{return tilemap_info.tiles[tile.name].ID;}}
保存与加载-2023/08/17
- 保存与加载代码的结构类似,
- 首先生成文件名,得到地图块在tilemap上的位置,
- 遍历 待保存/待读取 的数据,将地图块中的相对位置转为tilemap中的绝对位置,
- 将绝对位置上的数据 记录至二维数组/SetTile到tilemap
public void save_tilemap(Tilemap tilemap, int[] block_offsets){// file namestring filename = "Map_" + block_offsets[0] + "-" + block_offsets[1] + ".json";string file_path = "Assets/Resources/Saved/" + filename;// Get actual position of blockVector3Int map_offset = new Vector3Int(block_offsets[0] * block_size[0], block_offsets[1] * block_size[1]);// Init tilemap structTilemapInfo tilemap_info = new TilemapInfo {};tilemap_info.block_offset = block_offsets;tilemap_info.map = new List<List<string>>();// Loop for savingfor (int x = 0; x < block_size[0]; x++){List<string> map_row = new List<string>();for (int y = 0; y < block_size[1]; y++){// Get actual position of tileVector3Int tile_offset = new Vector3Int(map_offset[0] + x, map_offset[1] + y);TileBase tile = tilemap.GetTile(tile_offset);// Record tile infostring tile_ID = map_tile_to_ID(tile);map_row.Add(tile_ID);}tilemap_info.map.Add(map_row);}// savestring tilemap_info_json = JsonConvert.SerializeObject(tilemap_info, Formatting.Indented);File.WriteAllText(file_path, tilemap_info_json);}public void load_tilemap(Tilemap tilemap, int[] block_offsets){// read filestring filename = "Map_" + block_offsets[0] + "-" + block_offsets[1] + ".json";string file_path = "Assets/Resources/Saved/" + filename;if (!File.Exists(file_path)){// No datareturn;}string jsonText = File.ReadAllText(file_path);TilemapInfo block_info = JsonConvert.DeserializeObject<TilemapInfo>(jsonText);// Get actual position of blockVector3Int map_offset = new Vector3Int(block_offsets[0] * block_size[0], block_offsets[1] * block_size[1]);// Loop for loadingfor (int x = 0; x < block_size[0]; x++){List<string> map_row = new List<string>();for (int y = 0; y < block_size[1]; y++){// Get actual position of tileVector3Int tile_offset = new Vector3Int(map_offset[0] + x, map_offset[1] + y);string tile_ID = block_info.map[x][y];// Load tile TileBase tile = map_ID_to_tile(tile_ID);tilemap.SetTile(tile_offset, tile);}}
点击以保存/读取-2023/08/17
- 和Sec. 3.1的拖动鼠标放置tile的事件一样实现,首先鼠标位置转tilemap坐标,再转block位置,再运行保存函数与读取函数。
- 效果和想象的一样,挺好
if (input_base.isKeydown("Fire2")){Vector3Int pos_tilemap = tilemap_modify.WorldToCell(input_base.get_mouse_pos(1));int[] block_offset = {Mathf.Abs(pos_tilemap.x) / tilemap_base.block_size[0], Mathf.Abs(pos_tilemap.y) / tilemap_base.block_size[1]};if (pos_tilemap.x < 0){block_offset[0] = -block_offset[0] - 1;}if (pos_tilemap.y < 0){block_offset[1] = -block_offset[1] - 1;}Debug.Log("Mouse pos: [" + pos_tilemap.x + ", " + pos_tilemap.y + "].");Debug.Log("Block offset: [" + block_offset[0] + ", " + block_offset[1] + "].");tilemap_base.save_tilemap(tilemap_modify, block_offset);} if (input_base.isKeydown("Fire3")){Vector3Int pos_tilemap = tilemap_modify.WorldToCell(input_base.get_mouse_pos(1));int[] block_offset = {Mathf.Abs(pos_tilemap.x) / tilemap_base.block_size[0], Mathf.Abs(pos_tilemap.y) / tilemap_base.block_size[1]};if (pos_tilemap.x < 0){block_offset[0] = -block_offset[0] - 1;}if (pos_tilemap.y < 0){block_offset[1] = -block_offset[1] - 1;}Debug.Log("Mouse pos: [" + pos_tilemap.x + ", " + pos_tilemap.y + "].");Debug.Log("Block offset: [" + block_offset[0] + ", " + block_offset[1] + "].");tilemap_base.load_tilemap(tilemap_modify, block_offset);}
相关文章:

Unity记录4.3-存储-点击Tilemap保存或读取区块
文章首发见博客:https://mwhls.top/4816.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议,私信不回。 汇总:Unity 记录 摘要:点击tilemap,文件 保存/读取 该地图区块数据…...

【小吉测评】哔哩哔哩接入AI?!效果如何?
文章目录 🎄前言⭐申请方式🏳️🌈注意 🛸简介🍔上手体验🛸进行数学计算🥰可以写代码吗 🎄前言 最近人工智能特别火,chatgpt,Claude2,文心一言等…...

微信开发之一键踢出群聊的技术实现
简要描述: 删除群成员 请求URL: http://域名地址/deleteChatRoomMember 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选…...

基于Spring Boot 的 Ext JS 应用框架之coworkee
Ext JS 官方提供了一个人员管理的完整应用框架 - coworkee。该框架的显示如下: 该框架的布局特点如下: 布局方式: 左右布局, 左侧导航栏默认收合特点:左侧导航区占用空间小, 工作区较大, 适合没有二级导航栏,工作区需要显示的内容较多的系统。如果导航栏是横向底部,就…...

HOT100打卡—day10—【DP+多维DP】—最新8.29(剩6题)
DP 1 70. 爬楼梯 70. 爬楼梯 一次做,AC代码: 疑问:怎么判断用搜索还是dp?这题,我没有受过dp训练所以第一反应是用dfs搜索,找到所有符合要求的叶子。 class Solution { public:int dp[50]; // step1&a…...

【不会用这个工具,你的Linux服务器就是个摆设!】
01 Tcpdump Tcpdump 是一个强大的网络监控工具,它允许用户有效地过滤网络上的数据包和流量。 这可以获得有关 TCP/IP 和网络上传输的数据包的详细信息。 当你遇到网络协议问题一筹莫展的时候,这时候往往可以通过tcpdump来看网络的通讯过程中发生了什么…...

09 生产者分区机制
kafka如何保证消息的有序 可以通过key-ording策略解决。kafka可以为每条消息定义消息键,也称为key,通常是带有业务属性的比如用户id之类的。有相同消息键的消息会被发到同一个分区。下面实现了key-ordering策略,对key的hashcode进行取模来决…...

亚马逊鲲鹏系统是怎么操作测评的
亚马逊鲲鹏系统可以注册亚马逊买家号、养号、下单留评等,是一款功能比较齐全的测评软件,具体操作如下: 首先我们需要先准备好买家账号,账号可以直接去购买已经注册好了的账号,也可以准备好账号所需要的一些邮箱、ip、…...

电脑上的视频如何导入苹果手机?
AirDroid支持Windows、macOS、android、iOS相互传输文件、视频、图片等。 想要从电脑传输文件到iPhone也很简单,在电脑和iPhone都安装AirDroid,连接同一网络,然后登录同一个帐号就可以了。可绑定的iPhone数量不限,只要都登录同一…...

tsmc standard cell命名规则
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 CKMUX2代表二输入clock mux,D2代表驱动强度X2,6T代表row高为6track,16P96C代表gate length和poly pitch,LVT就是low voltage thr…...

基于ssm医院在线挂号预约系统源码和论文
基于ssm医院在线挂号预约系统源码和论文072 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 课题研究的目的及意义: 专家号难求,是医院现场挂号存在的主要问题之一,每一名专…...

mysql binlog 浅谈
如何开启MySQL的binlog日志 在MySQL中,binlog指的是binary log,二进制日志文件。这个文件记录了MySQL所有的DML操作。通过binlog日志,我们可以做数据恢复,做主从复制等等。对于运维或架构人员来说,开启binlog日志功能…...

three.js(八):内置的三维几何体
三维几何体 BoxGeometry 立方体TetrahedronGeometry 四面体OctahedronGeometry 八面体DodecahedronGeometry 十二面体IcosahedronGeometry 二十面体PolyhedronGeometry 多面体SphereGeometry 球体ConeGeometry 圆锥CylinderGeometry 圆柱TorusGeometry 三维圆环TorusKnotGeomet…...

IDEA 性能优化
前言 IDEA 基于JVM,是内存紧张型的应用,即使是16GB内存也很一般。 机器配置: win10 proi7-4720hq 3.2G 4c8tddr3-1600IDEA 2023.2.1 本文优化在不升级硬件的前提下使用 优化 调整JVM堆内存及GC IDEA 自身的JVM运行时配置,启动…...

react 获取表单中输入框的值
通过使用useState钩子来创建一个状态变量,你可以同时获取多个Input框的值。 1获取input框的值: import React, { useState } from react;function MyComponent() {const [forms, setForms] useState({name: ,nation: ,});const handleInputChange (e…...

[虚幻引擎 UE5] EditableText(可编辑文本) 限制只能输入数字并且设置最小值和最大值
本蓝图函数可以格式化 EditableText 控件输入的数据,让其只能输入一定范围内的整数。 蓝图函数 调用方法 下载蓝图(5.2.1版本)https://dt.cq.cn/archives/618...

Docker技术--Docker容器管理
1.Docker容器相关的指令(单个容器操) 我们之前在Docker中部署了一个实际应用的案例wordpress,其中使用到了一些相关于容器的指令,那么下面我们一起来总结使用。 Docker指令的语法规则如下所示: Docker + 命令关键字 [+参数选项] -1类:关闭、开启、重启、开启自启 systemct…...

three.js(七):内置的二维几何体
二维几何体 PlaneGeometry 矩形平面CircleGeometry 圆形平面RingGeometry 圆环平面 PlaneGeometry 矩形平面 PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer) width — 平面沿着X轴的宽度。默认值是1。height — 平面沿着Y…...

golang-bufio 缓冲读
缓冲 IO 计算机中我们常听到这样的两种程序优化方式: 以时间换空间以空间换时间 今天要来看的缓冲IO就是典型的以空间换时间,它的基本原理见上图。简单的解释就是:程序不再直接去读取底层的数据源,而是通过一个缓冲区来进行读取…...

前端 js实现 选中数据 动态 添加在表格中
如下图展示,表格上方有属性内容,下拉选中后,根据选中的内容,添加在下方的表格中。 实现方式,(要和后端约定,因为这些动态添加的字段都是后端返回的,后端自己会做处理,…...

MySQL—MySQL主从如何保证强一致性
一、前言 涉及到的东西:两阶段提交,binlog三种格式 1、两阶段提交 在持久化 redo log 和 binlog 这两份日志的时候,如果出现半成功的状态,就会造成主从环境的数据不一致性。这是因为 redo log 影响主库的数据,binlog…...

Lora升级!ReLoRa!最新论文 High-Rank Training Through Low-Rank Updates
目录 摘要1 引言2 相关工作3 方法4 实验5 结果6 结论7 局限性和未来工作 关注公众号TechLead,分享AI与云服务技术的全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员࿰…...

gateway动态路由和普通路由+负载均衡,借助eureka
gateway 中的动态路由和普通路由是相互独立配置的注意consumer使用了openFeign远程调用的配置文件中 prefer-ip-address: false 必须为false 否则 gateway的动态路由和负载均衡无法实现 spring:cloud:gateway:enabled: truediscovery:locator:enabled: true #表示动态路由&a…...

HTTP原理与实现
一、基本概念 一、基本原理* 1、全称: HyperText Transfer Protocol (超文本传输协议) 2、底层实现协议:建立在 TCP/IP 上的无状态连接。 3、基本作用:用于客户端与服务器之间的通信,规定客户端和服务器之间的通信格式。包括请…...

现在软件开发app制作还值得做吗
软件开发和制作App还是值得做的,但成功与否取决于多种因素。以下是一些影响你在软件开发和App制作领域发展的因素: 1、市场需求: 开发的App是否满足市场需求?是否解决了用户的问题或提供了有价值的功能?成功的App通常…...

java八股文面试[JVM]——类初始化过程
回顾类加载过程: 知识来源: 【2023年面试】Class初始化过程是什么_哔哩哔哩_bilibili...

什么是SQL注入攻击,解释如何防范SQL注入攻击?
1、什么是SQL注入攻击,解释如何防范SQL注入攻击。 SQL注入攻击是一种常见的网络攻击方式,攻击者通过在Web应用程序的查询语句中插入恶意代码,从而获取数据库中的敏感信息或者执行其他恶意操作。 为了防范SQL注入攻击,可以采取以…...

StringBuilder类分享(2)
一、StringBuilder说明 StringBuilder是一个可变的字符序列。这个类提供了一个与StringBuffer兼容的API,但不保证同步,即StringBuilder不是线程安全的,而StringBuffer是线程安全的。显然,StringBuilder要运行的更快一点。 这个类…...

IDEA查看类中的方法
做个记录 直接查看类中的方法,在打开的时候都会有。 查看单个类中的方法...

MySQL日期格式及日期函数实践
目录 日期格式 日期函数 CURDATE()和CURRENT_DATE()CURTIME()和CURRENT_TIME()NOW()和CURRENT_TIMESTAMP()DATE_FORMAT()DATE_ADD()和DATE_SUB()DATEDIFF()DATE()DAYNAME()和MONTHNAME() 1. 日期格式 在MySQL中,日期可以使用多种格式进行存储和表示。常见的日期格式…...