Vectania Editor(三)|当角色开始回应:模型与状态动画如何形成可交互虚拟人

Vectania Editor|AI 生成内容产品体验|字数 3,670|阅读时长 ≈ 10 分钟

第一篇里,我给角色搭好了工作区、路径和图层。第二篇里,位置、透明度和路径进入 Timeline,分散的 Clip 也被放进 State Graph。

可当动画播放起来,我还是觉得少了点什么。

眼睛会移动,嘴角也会抬起,但它们像住在同一张脸上的两位室友:地址相同,各忙各的。角色稍微复杂一点,我就要同时照看更多图层、轨道和彼此牵连的数值。

动作有了,身体却还没有形成。

我需要的不是再加几排关键帧,而是让运动属于角色本身。

这是系列的第三篇。前半篇沿着原生 2D ModelBoard,经过 Image Mesh、Warp、Rotation Deformer 和参数控制;后半篇切到 Artboard 里的 Live2D 节点,追踪参数如何进入 Timeline 与 State Machine。

它们不是同一个模型实例,却共享一门重要的语言:动画只需改变角色参数,不必逐一操心几何细节。

ModelBoard、Artboard 与参数面板的全局关系
ModelBoard、Artboard 与参数面板的全局关系

图 1:同一份工程里既有原生 2D ModelBoard,也有承载 Live2D 节点的 Artboard;参数面板会跟随选择。右侧的 No 3D 只说明测试工程没有放入 3D 内容。

关键不在多动几层,而在让它们一起动

属性动画擅长记录事实:第 0 帧的 X、第 20 帧的透明度,或一条 Path 在第 40 帧的形状。

角色动作却很少只属于一个属性。转头时,眼睛、眉毛、嘴和脸部轮廓要保持关系;眨眼时,眼皮不能把眼球留在原地;身体摇摆时,局部既要跟随,也要保留细节。

如果继续为每个图层分别写关键帧,“向右看”很快会变成一张购物清单:眼睛挪一点,眉毛跟一点,嘴角再补一点。动画能够播放,却很难修改和复用。

模型先定义部件如何协作,再让动画改变它们共同理解的输入。Timeline 不必知道每个网格点该去哪里,只需记录此刻的 角度 X左眼 开闭嘴 开闭

模型不是更多图层的集合,而是一组可以反复使用的身体关系。

ModelBoard 先把身体关系说清楚

测试工程里有两个 2D ModelBoard,也有用于动画演示的 Artboard。它们都以 Frame 为容器,但关注不同的问题:Artboard 关心场景与 Clip;ModelBoard 关心图片部件、Mesh 和参数绑定。

放大后的 2D ModelBoard
放大后的 2D ModelBoard

图 2:ModelBoard 展示组装后的脸;左侧图层标记 Mesh,参数栏列出角度、眼睛、眉毛、嘴形、呼吸与头发等控制维度。

我最初把 ModelBoard 理解成“功能更多的 Artboard”。实际使用后,它们更像化妆和登台:前者整理身体结构,后者安排动作与场景。

这是职责差异,不代表它们必须占用两块画板。当前项目允许同一个 Frame 同时成为 ModelBoard 与动画 Artboard,让原生模型参数和 Clip 留在同一作用域。

ModelBoard 声明的是一种编辑语境。多个模型可以分放在多个 Frame;原生 2D ModelBoard 若要让参数进入 Clip,则由同一 Frame 兼任动画 Artboard。无论界面怎样摆放,我都要知道自己正在修改身体关系,还是它随时间发生的变化。

Mesh 给图片铺一张会弯的网

导入图片后,编辑器先得到一个矩形边界。它适合移动、缩放和旋转,却表达不了眼皮弯曲或嘴角抬起。

Mesh 在图片上铺一张网。像素仍来自原图,顶点和三角面决定网格变形时,图像如何重新映射。

Image Mesh 形变编辑
Image Mesh 形变编辑

图 3:选中眉眼附近的 Image Mesh 后,34 个网格点直接叠在角色上;右上角面板控制形变半径与衰减。

当前项目会先为进入 ModelBoard 的图片补一层基础网格,Auto Mesh 还能按矩形或轮廓继续布点。图 3 的 34 个点也暴露了取舍:点太少,表情像纸板;点太多,编辑成本迅速上升。

合适的网格不追求最多顶点,只需刚好表达动作。

Mesh 也不是动作本身。它把像素结果翻译成几何结构,让 Deformer、参数和动画能够共同作用在同一块表面上。

Deformer 决定这块身体怎样动

有了 Mesh,我可以逐点拖动。但如果每个姿态都从挪点开始,只是把“逐层写关键帧”换成了“逐点搬家”。

Deformer 把一组点组织成更有意义的控制关系。

Warp Deformer 用控制笼包住图片。拖动控制点时,Mesh 连续弯曲,适合眉毛弧度、眼皮闭合和柔软部件摆动。

Warp Deformer 控制笼
Warp Deformer 控制笼

图 4:绿色控制点与红色边界说明眉眼区域将怎样弯曲。

Warp 不是视觉滤镜。它是图层树里的真实容器,原来的 Mesh 仍位于其中。选中 Warp 时,检查器会显示受影响的图片、姿态来自静态控制笼还是参数绑定,以及层级关系能否烘焙。

Warp Deformer 的层级与检查器
Warp Deformer 的层级与检查器

图 5:图层树、控制笼和检查器共同指向同一个 Warp Deformer。

Rotation Deformer 处理另一类关系。它不揉捏表面,而是用 pivot、角度和半径,让一组内容围绕固定位置旋转。眼球、手臂或配件更像装在铰链上的部件,关键问题不是“哪里弯了”,而是“绕哪里转”。

Rotation Deformer 的枢轴控制
Rotation Deformer 的枢轴控制

图 6:Rotation Deformer 显示 pivot、旋转半径与方向,检查器保留受影响图片和静态角度。

Warp 与 Rotation 都会改变画面,但它们描述的身体关系不同:一块连续弯曲的表面,或一个围绕支点运动的部件。关系选对后,少量控制就能解释多种姿态;选错后,每个新动作都会要求额外补偿。

参数把几何暗号翻译成角色语言

Mesh 和 Deformer 解决了“怎样变化”,还没回答“为什么变化”。如果 Timeline 仍要定位某个 Deformer,再写入局部坐标,模型和动画就会紧紧耦合。

参数在中间提供一套稳定语言。

测试模型有 28 个参数,包括角度、眼睛开闭、眉毛、嘴形、呼吸和头发摆动。它们不是最终的几何属性,而是角色暴露给动画与状态系统的控制词汇。

角度 X / Y 会组成二维控制面。拖动红点时,我告诉模型“看向右上方”,不用逐个移动顶点。

二维参数控制模型姿态
二维参数控制模型姿态

图 7:把 角度 X / 角度 Y 移到右上区域后,多个脸部 Mesh 共同求值,形成连续的转头姿态。

到这里,角色不再只是一叠图层。画布上仍是那些图片,背后也仍是 Mesh 顶点,但我操作的是“看向右上方”,不是“把第几个点移动多少像素”。

参数也划清职责:模型把输入解释成姿态,Timeline 让输入随时间变化,State Machine 决定何时采用哪组输入。ModelBoard 保存模型参数与绑定;Timeline 和 State Machine 播放时只生成临时结果。彩排不会改写角色底稿。

两条模型路径,在参数层会合

这里必须先说明一处边界。

图 2 至图 7 展示的是 Frame 30 上的原生 2D ModelBoard。从图 8 开始,测试工程切到 Frame 11 对话情绪切换,其中承载独立的 Live2D 1 节点。后半段不是把前面的 ModelBoard 搬进 Artboard,也不是同一个模型换了名字。

当前项目让原生 ModelBoard 的参数动画在 Clip 所属的同一个 Frame 内求值;它还不能把整块 ModelBoard 当成通用实例,再放入另一块 Artboard。Live2D 则拥有自己的模型资源、参数目录和运行时,可以作为节点进入 Artboard。

两条路径的身体结构不同,却都接受“转头、闭眼、微笑”这类参数输入。

测试工程为 Live2D 1 准备了 开心微笑难过摇头表示不知道喋喋不休伤心难过 五段 Clip。切到 Anim 后,Timeline 展开的正是这个 Live2D 节点的参数轨道。

Artboard 中的 Live2D 节点与 Timeline
Artboard 中的 Live2D 节点与 Timeline

图 8:Frame 11 承载 Live2D 1;当前 Clip 展开它的角度参数关键帧。

普通图层记录 Position、Opacity 或 Path;Live2D 节点记录 角度 X左眼 开闭右眼 微笑眼珠 X 等参数。

Live2D 参数在 Timeline 中的关键帧
Live2D 参数在 Timeline 中的关键帧

图 9:关键帧记录“何时转头、何时闭眼”,不直接改写 Live2D 内部几何。

Timeline 只安排意图何时变化,具体几何怎样响应,仍由 Live2D 模型与运行时解释。这正是参数的价值:原生 ModelBoard 用它驱动 Image Mesh 和 Deformer,Live2D 用它驱动自己的模型;Timeline 不必学习两套几何方言。

一段动作怎样成为一次回应

一段 开心微笑 Clip 仍然只是一句准备好的台词。交互的关键,是让外部输入改变状态,再由状态选择 Live2D 此刻执行哪段参数动画。

在 State Graph 中,五段对话情绪成为五个可互相转换的状态。示例把它们放在一个 motion Layer:开心微笑 是默认状态,其他状态通过条件进入,也可以返回或继续前往新的情绪。一个 Layer 已经能讲清因果链,无需把所有层级能力都挤进同一张图。

Live2D 对话情绪 State Graph
Live2D 对话情绪 State Graph

图 10:五段 Live2D 参数动画成为状态节点,关系线说明情绪之间如何转换。

把 State Graph 放回整个工作区,上方的 Frame 30 ModelBoard 与当前的 Frame 11 Live2D Artboard 会同时出现。它们共存在一个工程,但这张状态图只属于 Frame 11,不会控制上方 ModelBoard 的网格。

ModelBoard、Live2D Artboard 与 State Graph 全景
ModelBoard、Live2D Artboard 与 State Graph 全景

图 11:两种模型共存在工程中;下方 State Graph 只组织当前 Frame 11 的 Live2D 行为。

第二篇已经用 State Machine Debug 验证过矢量动画。这里沿用相同操作:选择 clip、Apply,需要时 Interrupt 或推进 1 帧,再看 Resolved Runtime 落在哪个状态。不同之处只在于,这次选中的 Clip 携带 Live2D 参数轨道。

状态机输入与解析后的 Live2D 状态
状态机输入与解析后的 Live2D 状态

图 12:clip=开心微笑 提供明确输入;Resolved Runtime 显示当前情绪状态、Transition 与播放结果。

这还不是观众使用的交互界面,而是一张行为实验台。我给出输入,检查状态如何选择 Clip,Clip 如何改变参数;结果不对时,再沿原路返回 State Graph、Timeline 和参数轨道。

可交互不等于多一个播放按钮。它需要一条可追踪的因果链:输入改变状态,状态选择动画,动画改变参数,参数交给模型解释。

路径不同,因果关系可以一致

这组截图没有把原生 2D ModelBoard 和 Live2D 拼成同一个闭环。它记录了两段真实工作:前半段在 ModelBoard 建立可控的身体关系,后半段让独立 Live2D 节点通过参数动画和状态回应。

它们共享外层因果关系,内部路径仍然分开:

Codemermaid
图表将在进入视口后显示

原生 2D ModelBoard 也能在自己的 Frame 内使用参数轨道和 State Machine。启用 2D Physics 后,它会在参数与 Rig 之间加入惯性、延迟和联动,不会另造网格或直接推动顶点。这组截图没有展示该链路,因此图中标注的是项目现状,不是截图结论。

本文的 2D 建模示例以图片为主,只聚焦 Image Mesh、Warp 和 Rotation。项目还支持 Bone 与 skin weight、Image Mesh Deform Path,以及兼容旧文档的 Path Deformer。直接绘制的 Path 能进入 Timeline,但它还没有与 Image Mesh 完全一致的建模和绑定体验。

图 1 的 No 3D 也只描述当前工程。项目已有独立 3D ModelBoard,支持 VRM / GLB、表情、骨骼姿态、配饰,以及 Timeline / State Machine 求值;它使用 Three.js 的独立运行路径,不与 Pixi 2D Rig 或 2D Physics 混用。本文没有 3D 示例,因此不再展开。

下一步要打磨的,是日常使用中最容易硌手的环节:Mesh 能否快速布得恰到好处,Deformer 的创建与绑定是否一致,参数重命名或删除后能否可靠清理引用,动画播放与状态切换是否始终可预测。

闭环存在是一回事,经得起反复修改是另一回事。

虚拟人不是由一个模型、一段动画或一张状态图单独拼成的。不同模型可以走不同路径,但那根叫作“意图”的接力棒不能掉:输入为什么触发这个状态,状态为什么选择这段动画,参数最后交给哪个模型,都应该找得到答案。

现在,我至少能沿着一次回应,走回它的起点。


本文记录的是当前阶段的个人自用工作流。截图来自用户指定的本地测试工程;Warp 与 Rotation 示例在隔离浏览器会话中临时创建,截图完成后未写回源工程。

0