我们想在自家游戏(名为 Dead Broke,如果你想支持我们 🙏)的 UI 中加入一些骨骼动画,使其外观更自然。

我们选择使用 Unity 的 2D Animation 包,因为它已经提供了我们所需的所有功能来 rig(骨骼绑定)和动画精灵。

问题是该包依赖于 Sprite Renderer,它们与 Canvas 系统配合得不太好,尤其是在使用 Screen Space Overlay Canvas 时。

因此我们决定构建一个小型自定义组件来解决这个问题。

想法很简单:与其使用 Sprite Renderer,我们创建了一个自定义的 UI Graphic,它接收已 rig 的精灵数据并填充 UI 网格。

由于它继承自 MaskableGraphic,它可以直接在 Canvas 中使用,并支持常规 UI 功能,如遮罩。

在动画方面,我们获取每个顶点的骨骼索引和权重,使用骨骼矩阵计算变形,并更新 UI 几何体。

所有操作都在 LateUpdate 中进行,因此动画应该已经完成。

这虽然工作得相当好,但意味着顶点位置需要每帧在 CPU 上重新计算。

因此我们还实现了 GPU 皮肤动画(GPU skinning)。

与其在 CPU 上计算最终顶点位置,我们通过额外的 UV 通道将原始位置、骨骼索引和权重传递给着色器。

着色器随后在顶点阶段直接进行皮肤动画。

这样,GPU 在渲染时处理变形。

此外,Screen Space Overlay Canvas 有特定的小问题,常规的矩阵变换在 Game 视图中未产生预期结果。

我们不得不添加一个小的变通办法来处理这种情况。

结果是一个组件,让我们能够直接在 UI 中使用已 rig 的 2D 精灵,支持骨骼动画、UI 遮罩以及 CPU 和 GPU 皮肤动画。

我们最初是因为自身游戏的需求而构建它,但发现它足够有用,觉得值得分享。

我整理了一份更详细的工作原理说明,包含部分实现细节,并免费在我们的 Patreon 上发布,供有兴趣的朋友参考:

Full Breakdown

而且,这全部都是我们第一款游戏 Dead Broke 的开发的一部分!

我们仍在努力完善演示,如果项目听起来对你有兴趣,将其加入 Steam wishlist 将对我们帮助极大。

Steam page

感谢阅读!

如果你在 Unity 中遇到过类似的问题,我很想听听你是如何处理的。

PS: 视频中的内容不是游戏的 UI,只是为了说明而创建的示例。