引言
CocosCreator3.8实现动态切割模型
大家好,不知道小伙伴们还记不记得切水果这个游戏,这个游戏在当年智能触屏手机刚出来的时候,可谓风靡全球。
小伙伴们在刚开始学习做游戏的时候,有没有自己动手做过一个切水果的项目练练手呢?笔者可是历历在目。
言归正传,今天给大家介绍一下如何在CocosCreator3.8中实现动态切割模型。
本文源工程在文末阅读原文获取,小伙伴们自行前往。
1. 实现动态切割模型的知识点
实现动态切割模型涉及到多个知识点,包括但不限于以下内容:
-
屏幕画线,射线:
- 你可以通过画线组件来绘制线条。
- 射线是从一个点出发,沿着特定方向无限延伸的直线,通常用于进行碰撞检测、光线追踪等操作。
-
Mesh操作基础:
- 了解
Mesh
的基本概念,包括顶点、面片、法线、UV
等属性。 - 熟悉Mesh数据结构及其在引擎中的表示方式。
- 了解
-
几何运算:
- 掌握几何运算的基本原理,例如点与平面的关系、向量运算等。
- 理解如何使用几何运算来进行
Mesh
的切割操作,包括点与面的关系、线段与面的关系等。
-
动态Mesh更新:
- 实现动态更新
Mesh
数据的方法,包括顶点坐标、法线、UV
等属性的修改。 - 理解如何利用引擎提供的
API
来更新Mesh
数据,以实现动态切割效果。
- 实现动态更新
2. 实现动态切割模型的核心内容
在CocosCreator3.8
中实现动态切割模型的核心内容如下,小伙伴们可以先行了解一下:
1.MeshRenderer 组件
MeshRenderer
(网格渲染器)组件用于显示一个静态的 3D 模型。通过Mesh
属性设置模型网格,通过Materials
属性控制模型的显示外观。
在 属性检查器 中点击 添加组件 -> Mesh
-> MeshRenderer
即可添加 MeshRenderer
组件。
2.网格资源
Mesh
资源是渲染网格的必要资源,目前网格主要是在 导入模型资源 到Creator
中时,由Creator
自动生成的。
Mesh
资源中包含了一组顶点和多组索引。索引指向顶点数组中的顶点,每三组索引组成一个三角形。
网格则是由多个三角形组成的,是
3D
世界中最基本的图元。多个三角形拼接成一个复杂的多边形,多个多边形则拼接成一个
3D
模型。
3.程序化创建网格
当由建模软件制作或引擎内的地形编辑器制作的模型无法满足需求时,可以通过
API
来创建网格。如需要在运行时创建某种可以生长的蛇、动态编辑模型或实现某些曲面,都可以通过程序化来创建网格。
在CocosCreator3.8
中支持两种网格:静态网格 和 动态网格,适用于不同的场景,小伙伴们可按需使用。
- 静态网格,通过
utils.MeshUtils.createMesh
创建,一旦创建成功,网格内的几何体不可编辑的。 - 动态网格:通过
utils.MeshUtils.createDynamicMesh
创建,创建成功后,网格内的几何体仍然可以修改。
返回值为 Mesh
组件,因此我们方便的将其赋值给 MeshRenderer
的 mesh
属性,如此即可将其显示在屏幕上。
3. 动态切割模型的Cocos实例
1.资源准备
首先我们还是先去找一找有没有巨人的肩膀可以踩一下。
很不幸的是,笔者翻云覆雨地找了一下,并没有相关现成的Cocos
代码或者算法可以借鉴参考一下(没找到,不代表没有)。
但是,笔者惊奇地发现,github
上有那么一个仓库,骨骼惊奇,代码清晰易懂,重点还不带半点注释。
好家伙,7年前的宝藏仓库。还是C#
代码。
与此同时,为了更好的节目效果,我们还是去找美术妹子要一点美术资源。
2.翻译
由于仓库是隔壁油腻体的C#
代码,没办法直接使用,我们需要进行翻译一下。
关于翻译,以下有几种方案:
- 理解源码,超越源码。充分学习算法之后,自己重新实现一遍。
- 理解源码,手动翻译。简单了解算法之后,一对一翻译。
- 不理源码,工具翻译。利用一些现成的工具或者正则匹配进行大部分翻译。
- 复制源码,AI来帮你。利用时下热门的AI工具,帮你翻译。
3.源码解析
第一步
首先创建一个SplitInput
组件,用于画线和通过射线获取切割物体。初始化一下摄像机和Graphics
组件。
然后是监听我们的屏幕滑动四件套(F4
),以及简单的画线逻辑。
接着通过我们画的线,利用插值获取线上的点再和摄像机发出射线,检测线段是否切割到物体。
最后利用我们画的线和射线得出平面的法线(两向量的向量积)、射线与物体碰撞的点,通过geometry.Plane.fromNormalAndPoint
形成我们的切割平面。
大致效果如下:
第二步
创建一个MeshInfo
网格信息管理类。主要负责网格信息的读取:
核心API如下:
mesh.readAttribute(0, gfx.AttributeName.ATTR_POSITION);
以及网格的创建:
核心API如下:
utils.MeshUtils.createMesh
第三步
创建一个SplitObject
组件,需要有这个组件的物体才可以被切割。
切割网格的核心算法,首先把顶点根据平面划分成上下两个部分:
核心公式:
Vec3.subtract(v3(), vert, point).dot(normal) >= 0;
然后把顶点的索引进行划分:
切割的分割点的顶点、UV、法线、切线、索引等算法,比较简单,不想理解的可以直接使用:
其实,网格的切割就是把每一个三角形进行切割,并且根据情况把切割点添加到两部分,重新生成三角形和索引。图示如下:
但是,我们进行划分和重新索引之后,切割面还没处理,会有镂空的感觉,情况如下:
于是我们需要对切割面进行填充:
这样效果就比较合理了:
最后切割完成后,把两部分的网格和节点重新生成,更新MeshCollider
,简单添加一下位移动画则大功告成。
4.注意事项
- 注意本地坐标与世界坐标的转换。
- 先把所有需要切割的物体检测出来再进行切割。
- 留意平面法线的方向。
- 重构索引时顶点的方向。
-
Mesh
创建时的其他属性可以通过customAttributes
自定义。 - 当模型顶点过多时,需要对算法进一步优化。
5.效果演示
切割效果如下。
切换编辑器看下:
逐渐疯狂:
切方块不够解压?最后再来切个瓜。
注意,西瓜的切割面没做处理,不能食用,感兴趣的小伙伴可以自行研究和探讨。
结语
以上是在CocosCreator3.8中实现动态切割模型的所有内容。
需要源工程的小伙伴可通过阅读原文(付费)获取,原创不易,感谢大家的支持。
往期回顾: