引言
哈喽大家好,我是亿元程序员。
前阵子我发了一篇割绳子游戏实战的文章,其中核心在于如何制作一根不像棍子的物理绳子,受到小伙伴们的一致好评:
但是也有小伙伴认为绳子缺少纹理不够完美:
看到这,我就笑了,哈哈,非常感谢小伙伴提供的素材,绳子的确可以优化成带有纹理的绳子。
言归正传,本期带大家一起来实战看看,如何通过自定义Assembler实现一根带有纹理的绳子。
本文源工程可在文末获取,小伙伴们自行前往,有体验链接。
为什么要有纹理?
因为没有纹理的线:
- 像棍子
- 像塑料吸管
- 像程序员的头发(越来越少)
具体到游戏有割绳子游戏中的绳子纹理,箭头游戏中把箭头换成蛇或者其他皮肤。
Cocos自带的Graphics虽然能画线,但有个问题就是不支持纹理。
所以本期我们就一起来实现一个。
实现纹理画线有哪些办法?
想要实现纹理画线,笔者能想到的,有且不局限于下面几种:
1.Sprite拼接
相信很多小伙伴第一反应能想到的就是这个方法,理论上当绳子的每一节越来越小,节数越来越多时,就会接近绳子的状态,否则绳子就会像双截棍一样。
2.MeshRenderer
通过自己生成Mesh(顶点 + 索引),用MeshRenderer和UIMeshRenderer进行渲染。
3.自定义Assembler
通过UIRenderer和Assembler,自己生成顶点数据,接入UI渲染管线(Assembler)。
喜欢看源码的小伙伴,可以看看Graphics组件和MotionStreak(拖尾)组件。
接下来我们就借鉴一下,通过Assembler实现纹理画线。
纹理画线实战
1.核心原理
-
UIRenderer :Cocos 所有 2D UI 组件的「渲染基类」(Sprite、Label 都继承它)。
-
Assembler : 负责把「坐标、UV、颜色」打包成渲染器能识别的顶点数据。
-
渲染流程 :
我们写路径坐标-> 生成顶点(UIRenderer)-> 组装器打包(Assembler)-> 提交 GPU 渲染。
根据上述流程,我们需要把“线”变成一条条三角形Mesh来画。
也就是:
一条线->展开成一个“带宽度的条带”->用三角形拼出来->再贴纹理
给大家画个图(别慌不是画饼):
三角形:
2.具体实现
新建一个TextureGraphics组件继承UIRenderer:
首先路径点的收集,避免游戏逻辑改动太多,笔者模拟了一套Graphics组件的API:
接着逐个将点沿着法线(垂直于方向)展开成两个顶点:
图示:
然后逐个生成三角形:
图示:
最后把数据更新到Assembler并且标记已修改,使得渲染数据可以重新计算:
3.Assembler
这是最重要的一层,负责把“线数据”变成GPU能画的顶点数据。
首先是创建createData,其中resize两个参数分别代表顶点数量和索引数量,updateRenderData是上面提到的更新数据接口:
然后就是最重要的一环fillBuffers打包数据了:
上面最主要做了四件事:
- 坐标转换并写入:通过矩阵将本地坐标转成世界坐标,把画的点变成屏幕位置
- 写入UV:控制纹理如何贴在线上
- 写入颜色:控制颜色
- 写入索引:控制“哪3个点组成一个三角形”
最后要指定Assembler:
4.使用
完成上面的操作之后,我们就可以和Graphics一样去使用它了,需要额外拖入一张纹理:
绳子图片就地取材,用的还是上次被指“像棍子”的那根:
写一个屏幕画线功能进行测试:
效果如下:
效果应用
功能没问题之后,我们就可以实际应用到游戏中去了。
由于我们做了适配,我们只需要将Graphics组件换成我们的TextureGraphics即可实现纹理画线:
效果如下:
效果出来后,我愣了几秒
结语
这,好像还是没有纹理好看点啊...
本文实战完整源码已集成到亿元Cocos小游戏实战合集(已完结),已经拥有的小伙伴可以直接更新。
我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。
实不相瞒,想要个赞和爱心!请把该文章分享给你觉得有需要的其他小伙伴。谢谢!
推荐文章: