V7投稿 | 如何在CocosCreator3.8中实现动态切割模型?

QQ录屏20240410054032~1

引言

CocosCreator3.8实现动态切割模型

大家好,不知道小伙伴们还记不记得切水果这个游戏,这个游戏在当年智能触屏手机刚出来的时候,可谓风靡全球。

小伙伴们在刚开始学习做游戏的时候,有没有自己动手做过一个切水果的项目练练手呢?笔者可是历历在目。

言归正传,今天给大家介绍一下如何在CocosCreator3.8中实现动态切割模型

本文源工程在文末阅读原文获取,小伙伴们自行前往。

1. 实现动态切割模型的知识点

实现动态切割模型涉及到多个知识点,包括但不限于以下内容:

  1. 屏幕画线,射线

    • 你可以通过画线组件来绘制线条。
    • 射线是从一个点出发,沿着特定方向无限延伸的直线,通常用于进行碰撞检测、光线追踪等操作。
  2. Mesh操作基础

    • 了解Mesh的基本概念,包括顶点、面片、法线、UV等属性。
    • 熟悉Mesh数据结构及其在引擎中的表示方式。
  3. 几何运算

    • 掌握几何运算的基本原理,例如点与平面的关系、向量运算等。
    • 理解如何使用几何运算来进行Mesh的切割操作,包括点与面的关系、线段与面的关系等。
  4. 动态Mesh更新

    • 实现动态更新Mesh数据的方法,包括顶点坐标、法线、UV等属性的修改。
    • 理解如何利用引擎提供的API来更新Mesh数据,以实现动态切割效果。

2. 实现动态切割模型的核心内容

CocosCreator3.8中实现动态切割模型的核心内容如下,小伙伴们可以先行了解一下:

1.MeshRenderer 组件

MeshRenderer(网格渲染器)组件用于显示一个静态的 3D 模型。通过 Mesh 属性设置模型网格,通过 Materials 属性控制模型的显示外观。

在 属性检查器 中点击 添加组件 -> Mesh -> MeshRenderer 即可添加 MeshRenderer 组件。

image

2.网格资源

Mesh 资源是渲染网格的必要资源,目前网格主要是在 导入模型资源 到 Creator 中时,由 Creator 自动生成的。

Mesh 资源中包含了一组顶点和多组索引。

索引指向顶点数组中的顶点,每三组索引组成一个三角形。

网格则是由多个三角形组成的,是 3D 世界中最基本的图元。

多个三角形拼接成一个复杂的多边形,多个多边形则拼接成一个 3D 模型。

image

3.程序化创建网格

当由建模软件制作或引擎内的地形编辑器制作的模型无法满足需求时,可以通过 API 来创建网格。

如需要在运行时创建某种可以生长的蛇、动态编辑模型或实现某些曲面,都可以通过程序化来创建网格。

CocosCreator3.8中支持两种网格:静态网格 和 动态网格,适用于不同的场景,小伙伴们可按需使用。

  • 静态网格,通过 utils.MeshUtils.createMesh 创建,一旦创建成功,网格内的几何体不可编辑的。
  • 动态网格:通过 utils.MeshUtils.createDynamicMesh 创建,创建成功后,网格内的几何体仍然可以修改。

返回值为 Mesh 组件,因此我们方便的将其赋值给 MeshRenderermesh 属性,如此即可将其显示在屏幕上。

image

3. 动态切割模型的Cocos实例

1.资源准备

首先我们还是先去找一找有没有巨人的肩膀可以踩一下。

很不幸的是,笔者翻云覆雨地找了一下,并没有相关现成的Cocos代码或者算法可以借鉴参考一下(没找到,不代表没有)。

但是,笔者惊奇地发现,github上有那么一个仓库,骨骼惊奇,代码清晰易懂,重点还不带半点注释。

https://github.com/carefreeq/SplitMesh

好家伙,7年前的宝藏仓库。还是C#代码。

image

与此同时,为了更好的节目效果,我们还是去找美术妹子要一点美术资源。

image

2.翻译

由于仓库是隔壁油腻体的C#代码,没办法直接使用,我们需要进行翻译一下。

关于翻译,以下有几种方案:

  • 理解源码,超越源码。充分学习算法之后,自己重新实现一遍。
  • 理解源码,手动翻译。简单了解算法之后,一对一翻译。
  • 不理源码,工具翻译。利用一些现成的工具或者正则匹配进行大部分翻译。
  • 复制源码,AI来帮你。利用时下热门的AI工具,帮你翻译。

image

3.源码解析

第一步

首先创建一个SplitInput组件,用于画线和通过射线获取切割物体。初始化一下摄像机和Graphics组件。

image

然后是监听我们的屏幕滑动四件套(F4),以及简单的画线逻辑。

image

接着通过我们画的线,利用插值获取线上的点再和摄像机发出射线,检测线段是否切割到物体。

image

最后利用我们画的线和射线得出平面的法线(两向量的向量积)、射线与物体碰撞的点,通过geometry.Plane.fromNormalAndPoint形成我们的切割平面。

image

大致效果如下:

image

第二步

创建一个MeshInfo网格信息管理类。主要负责网格信息的读取:

image

核心API如下:

mesh.readAttribute(0, gfx.AttributeName.ATTR_POSITION);

以及网格的创建:

image

核心API如下:

utils.MeshUtils.createMesh

第三步

创建一个SplitObject组件,需要有这个组件的物体才可以被切割。

image

切割网格的核心算法,首先把顶点根据平面划分成上下两个部分:

image

核心公式:

Vec3.subtract(v3(), vert, point).dot(normal) >= 0;

然后把顶点的索引进行划分:

image

切割的分割点的顶点、UV、法线、切线、索引等算法,比较简单,不想理解的可以直接使用:

image

其实,网格的切割就是把每一个三角形进行切割,并且根据情况把切割点添加到两部分,重新生成三角形和索引。图示如下:

image

但是,我们进行划分和重新索引之后,切割面还没处理,会有镂空的感觉,情况如下:

image

于是我们需要对切割面进行填充:

image

这样效果就比较合理了:

image

最后切割完成后,把两部分的网格和节点重新生成,更新MeshCollider,简单添加一下位移动画则大功告成。

image

4.注意事项

  • 注意本地坐标与世界坐标的转换。
  • 先把所有需要切割的物体检测出来再进行切割。
  • 留意平面法线的方向。
  • 重构索引时顶点的方向。
  • Mesh创建时的其他属性可以通过customAttributes自定义。
  • 当模型顶点过多时,需要对算法进一步优化。

5.效果演示

切割效果如下。

QQ录屏20240410065657

切换编辑器看下:

QQ录屏20240410065812

逐渐疯狂

QQ录屏20240410070001

切方块不够解压?最后再来切个瓜。

注意,西瓜的切割面没做处理,不能食用,感兴趣的小伙伴可以自行研究和探讨。

QQ录屏20240410070052

结语

以上是在CocosCreator3.8中实现动态切割模型的所有内容。

需要源工程的小伙伴可通过阅读原文(付费)获取,原创不易,感谢大家的支持。

往期回顾:

V7投稿 | 如何在CocosCreator3.8中实现割绳子游戏效果

10赞

谢谢大佬,学习了

很强,顶一个!

666666666666 :partying_face: :partying_face: :partying_face: :partying_face:

20240411-094134

最近也在做一个模型切割的游戏,本来也想写一篇文章,没想到大佬抢先了 :+1:

3赞

牛啊牛啊牛

你们咋就都这么厉害呢,我这脑袋死活算不明白。。。

我也有个一样的文章 :rofl:

我也有个, 2dx的
SmashTetris_2024-04-11_10-58-29

1赞

你这个好玩! :rofl:

我抄的那个竞品游戏就是这样,需要边切割边弯曲。所以把切下来的部分又细分了网格,然后再在shader里弯曲。

:rofl:尴尬

学习了,收藏了

马赛克大佬那工程我下载下来看了,切个几刀fps就到40左右了,这个有办法优化吗?

这个转着圈切了7刀,fps就到33了
image

我用的网格碰撞体,你可以关闭物理引擎。网格碰撞是比较消耗性能的