上一篇文章(https://forum.cocos.org/t/topic/140242/36),
我介绍了24小时开发 羊了个羊3D版的流程,其中很重要的一环就是场景编辑器,很多老师提出了疑问,为什么要使用Cocos再做一个编辑器,而不是直接把整个关卡保存为预支体。
之前游戏体验:learncocos.com/miao
编辑器体验地址:learncocos.com/miaoeditor
为什么要做场景编辑器
先聊一下序列化问题
序列化: 指把Cocos的场景数据,通过某种方式把场景中的节点信息和组件信息存储为Scene(场景文件),或者储存为Prefab(预支体)。这个过程称为序列化。通俗来说就是将节点的数据结构或对象转换成Json数据流的过程。
反序列化: 把磁盘文件中的场景文件或者预支体文件,还原成节点和组件的过程。也就是将在序列化过程中所生成的Json数据流还原成场景的过程。
下面分别使用引擎和地图编辑器制作1个小场景,并对比下区别。

首先对比下引擎生成的Prefab的Json文件,整个大小超过了10KB,引擎需要知道节点信息中的依赖关系(UUID)和所有节点信息(这是必要的,确保功能的完整性和扩展性),所以整个Json文件,信息完整,同时具有良好的兼容性和可扩展性。

我们再用地图编辑器生成一个相同的场景

大小只有120字节,体积节省了近98%以上。

不仅Json的体积小了,减少了加载时IO开销,同时数据结构也精简了许多,解析和加载速度也更快。
但是这并不意味着游戏内所有的场景都使用自定义的编辑序列化会更好,针对复杂的UI场景做编辑器,1是开发时间巨大,2是无法做到像引擎预支体一样良好的兼容性和可扩性,和可迭代性。
加载问题
引擎默认的预支体建议使用Assetbundle 进行本地或者远程加载,如果更新了预支体,需要重新打包bundle进行替换,而使用自定义编辑器+Json格式,可以把关卡信息储存到服务器上,实时加载与更新。

反序列化
使用引擎默认的预支体,反虚化时候,需要同时考虑到editor 和 gameplay 两种runtime,针对特定项目或者特大场景,使用自定义编辑器+Json在反序列化时候有3个点优势
速度优势 内容少,解析快
分帧优化 可以针对Json内数据做分帧加载,分帧实例化,减少黑屏时间
自定义效果 可以在实例化时候自定义效果,如放大缩小,位置移动等(都可以通过tween实现)
如何实现地图编辑器功能
数据设计
考虑到可能有很多自定义预支体 , 无法确认他们的名字和位置 , 这里使用了Assetbundle里的 loaddir 类型 , 通过property 自定义bundle名字和需要加载的文件夹路径 。

把整个文件夹下面的物体都加载并实例一个对应的toggle,方便做切换。

在数据储存上就比较灵活了,只需要维护特定bundle下的特定文件夹就行了。
地图检测
喵了个喵在地图设计上可能会存在空缺的情况,所以无法单纯的使用射线检测rayModel去获取方块的位置信息,这里使用了层级的方法,可以使用123456789进行层级切换,或者按tab向上移动层级,只需要检测每个层级上的网格就行了(层级切换的时候网格也会进行切换)

网格自适应
由于需要对网格进行设置 , 可以通过自定信息用的长度宽度和格子大小来改变网格的信息 , 通过长度 , 宽度和格子大小相乘后设置网格的Scale ( 默认的Quad长宽分辨是 1 个世界坐标 )


同时对网格的shader也做了tilingoffset的设置。

Shader里对每5格的网格宽度做了加宽处理,其他的网格做了颜色减弱,透明度只有93,效果如下。

数据查找
这里通过 1 个 3 层的数组做数据储存 , 主要是为了方便实例化 , 没有使用Map做查询 , 把射线与网格的交互点通过Math .round 运算转换成最近的网格点 , 和gripmap内的数据信息对比 , 没有则可以填充

数据缓存
摧毁物体和新增物体时候通过数组记录操作 , 和物体名字和节点信息 , 方便做还原

数据储存
把之前存储的信息先历遍 , 方便储存最高和最宽信息

把数组信息转换成string后通过浏览器 进行保存

资源读取
在编辑器环境下 , 把Json文件解析为UTF -8 的string , 再转换Json信息进行反序列化 。

商店地址:
https://store.cocos.com/app/detail/4124/
福利优惠群:(入群见公告领红包打骨折)


