动画状态机

阅读时间:5分钟更新于 2025-08-13 10:0

概览

什么是动画状态机?

「动画状态机」是一种将动画划分为不同“状态”并定义其切换逻辑的架构模式,它广泛应用于游戏开发、人机交互系统与高级 UI 动效设计中,是实现“响应式动画”的核心技术之一。

为什么你需要动画状态机?

传统方式

状态机方案

时间轴硬编码跳转

可视化逻辑图,逻辑清晰易维护

需开发介入实现交互

设计师独立完成交互动效

动画复用困难

模块化片段 + 参数化控制,高复用性

难以处理复杂状态

层级结构 + 混合模式,应对复杂场景

使用动画状态机可以非常方便地做互动类型的动画。观看下面的视频,可以直观了解状态机的运行原理及制作方法。

组成要素

一个动画状态机由以下几部分组成:

  • 状态】:简单来说,一个状态就是一段动画。比如将空闲、抽奖、按下、抬起、走路、跳跃等动画分别作为一个状态。
  • 切换条件】:从一个状态切换到另一个状态的条件。切换条件由参数控制。
  • 参数】:作为控制切换的实体。比如设置抬起到按下的切换条件为 pressDown 参数触发;或者设置播放抽中奖品2动画的条件为参数 winPrize 被设置为 2。
  • 事件监听】:监听目标元素的鼠标或手势事件,让指定的参数生效。比如监听按钮元素的按下(pointerdown)事件,然后触发 pressDown 事件,从而驱动状态机的状态流转。

下面分别展开介绍。

基础用法

状态

状态包含开始、动画这 2 种基础类型。

开始状态

表示动画的起始位置,从开始连出的第一个状态即为默认的动画状态。开始到默认状态之间不需要切换条件。

动画状态

一个动画状态由一段动画组成。一段动画由若干个元素的 K 帧组成。在状态的参数设置中可设定以下内容:

  • 名称:可自定义修改状态的名称。
  • 动画选择:指定当前状态播放的动画。
  • 播放速度:当前状态使用的动画的播放速度。
  • 循环:当前状态是否循环播放。

切换条件

切换条件以连线的形式存在。连线带有方向性,连线指示了从一个状态流出,然后流入到另一个状态。在连线的参数设置中可以设定以下内容:

  • 切换条件:设置可以发生状态切换的参数条件。图中的条件为 pressDown 参数被触发。
  • 退出时长:打开退出时长,且时间为 100%,则状态动画播放完成后,自动流入到下一个状态。
  • 融合时长:状态切换的动画属性的融合时长,单位为秒。设置融合时长可以避免硬切,可按需使用。

参数

参数有 3 种类型:

  • 布尔类型:值为 truefalse
  • 数字类型:值为数字。
  • 触发器类型:没有值,表示一次性触发。与布尔类型相比,使用触发器类型无需手动重置。

切换条件依据选中的参数类型不同,会自动展示不同的输入控件,如下图所示:

转换条件支持复合条件,在同个分组内的条件表示并,不同分组之间表示或。比如下面的切换条件为以下二选一:

  1. Number1 等于 2 且 Boolean1 等于 true
  2. pressDown 触发。

参数需要先在浮动的参数面板中创建:

事件监听

事件监听可以让设计独立完成一个交互而无需开发介入,比如篇首视频中展示的按钮点击交互。

事件在浮动的事件监听面板中创建:

在事件监听的参数设置中可以设定以下内容:

  • 目标元素:合成中的元素,目前支持的元素的类型有:图层元素、交互元素、文本元素、形状元素。
  • 监听事件:支持的事件有:点击(click)、按下(pointerdown)、抬起(pointerup)、拖拽移动(pointermove)。
  • 设置参数:目标元素发生监听的事件后,要修改的参数。同样这里的设置参数会根据参数类型展示对应的输入控件。

交互

创建状态机

合成的状态机在合成的参数设置中。状态机以控制器的形式存在。

方式一:通过合成的属性面板

点击画布空白处,可调出合成的参数设置。在下拉底部的输入框中输入状态机名称,点击【+】号,可添加一个控制器资源。

首次创建或切换合成会自动打开相应的状态机面板。若状态机面板被关闭,点击上图的笔图标,可以再次调起状态机面板。

方式二:通过资源管理器

资源管理器切到“动画”标签,然后点击【+】号,点击创建控制器。之后在合成的属性面板的下拉中选中这个控制器(同上一步)。

方式一创建的控制器资源也会展示在资源面板的动画列表中。

(方式一比方式二减少了调起资源面板的过程,看个人喜好)

创建动画

方式一:通过合成的属性面板

在合成属性面板的动画列表属性,点击【+】号创建动画资源。点击选中资源,按回车可重命名,按删除键可删除。

方式二:通过资源管理器

在资源管理器中,点击创建动画菜单,可创建动画资源。

使用动画

方式一:从合成的属性面板中,拖动动画到状态机面板中。

方式二:从资源管理器拖动动画资源到状态机面板中置放

高阶用法

层次状态机

层次状态机是指状态机中可以嵌套状态机,是一种分而治之的思想。举一个例子,角色有待机、行走、跳跃这 3 个状态,在任何状态中一旦触碰到敌人,则会切换到游戏结束状态。如下图所示:

如果没有层次状态机,那么这 3 个状态都需连到游戏结束,如下图所示:

而使用层次状态机,则可以增加一个游戏中的状态机状态,然后将待机、跳跃、行走移到这个状态机中。如下图所示,右键创建一个状态机状态,然后命名为“游戏中”。

双击“游戏中”,进入到这个状态机中,编辑游戏中的状态切换,如下图所示:

这样从“游戏中”切换到“游戏结束”,只需连一条线。只要这条连线的条件满足,就可以切换到游戏结束。
点击底部的导航可以回到对应的层级。

混合

Galacean Effects 提供了业界主流的动画混合模式,以满足不同场景的动效需求:

模式

说明

应用场景

1D(一维混合)

基于单参数线性插值(如速度值控制走/跑过渡)

角色运动渐变、进度驱动动画

Additive(相加混合)

在基础动作上叠加额外动画(如边走路边挥手)

叠加表情、手势微交互

Layered(分层混合)

多层动画独立控制(如上半身攻击 vs 下半身移动)

复杂角色控制、UI 多维度反馈

  • 1D:1 维混合是一种此消彼长的关系。
  • Additive:可以让 2 个动画或状态机进行属性值相加混合。
  • Layered:分层即为各层合并的意思,是最常用的一种混合方式,比如 3 个动画合并为一个状态,其中有的动画有循环,有的动画没有循环,或者循环的时间不一样。

1 维混合

通过右键菜单,创建一个动画混合状态,如下图所示:

在参数面板创建一个数字类型的参数,如下图所示:

然后在混合状态的属性面板中选中这个参数,并添加 2 个动画,一个是向上走,一个是向右走。

那么当 weight 等于 0 时,元素就会向上走。当 weight 等于 1 时,元素就会向右走。当 weight 偏向于 0 时,元素的行走角度会越偏向于垂直;当 weight 偏向于 1 时,元素的行走角度会越偏向于水平。该参数对元素的所有属性生效。

一个实际使用场景是控制角色的走路幅度。将角色的走路与跑步进行混合,然后用一个参数控制。当参数越靠近 1 时,就会走得越快。这样就可以通过一个参数来控制角色的走路快慢(配合位移)。

使用混合树,可以让状态机进行混合。首先创建一个混合树状态,如下图所示:

双击混合树状态进入编辑,如下图所示:

混合树同样通过一个权重参数控制混合效果。图中的 A 表示 0 端,B 表示 1 端。

我们让状态机状态与动画进行混合。混合树还可以嵌套混合树,形成级联的树形结构,如下图所示:

点击底部的导航可以回到对应的层级:

相加混合

相加混合的常用场景是混合不同元素的属性,或混合同一个元素的不同属性。让它们可以一起播放。相加混合的参数作用在第 2 个动画上,默认值为 1。

分层混合

分层混合可以将不同元素的属性或者同元素的不同属性进行合并。比如在以上例子中,当按下参数触发时,状态机从待机切到一个分层混合状态。这个状态由 3 个动画组成,其中前 2 个动画循环,后 1 个动画不循环。那么这个混合状态就合并了这 3 个动画的效果。

如果是同元素同属性,则后面的动画会覆盖前面的。制作时,如果出现混合中的动画不生效时,请检查是否在前面的动画中出现同元素同属性的情况。

模型元素的状态机

支持给模型的 TreeItem 元素添加状态机。在 TreeItem 的属性面板中添加状态机,如下图所示:

所有的制作方法都与上面描述的相同。合成的动画是在编辑器生产的,而模型的动画是导入进来的。所以动画需要从资源面板中拖到状态机面板中。

状态机的能力边界

状态机的适用场景存在以下限制:

  1. 仅适用于状态可枚举的场景。对于连续变化的场景则不适用,比较温度计的液体高度是连续变化的。如果能将连续的简化为离散数字,则可使用状态机。比如将温度计的液体高度变为 5 格。
  2. 状态之间的平滑衔接可能会受到限制。通过设置融合时间可以解决一部分问题。但有一些场景可能无法通过融合时间解决,需要通过编程解决或直接硬切。比如动画一旋转的角度从 0 转到 1440,切换到动画二是从 0 转到 360,如果切换到动画二设定融合时间,那么就会出现倒着转回去的情况。
  3. 状态可枚举,但过多,且两两个状态之间都可互相切换。如果有 n 个状态,总共就会有 (n - 1) + (n - 2)…+1 条连线。连线密密麻麻的,状态机就会变得难以维护。所以这种情况编程实现(状态机)可能是更优解。

开发控制状态机

开发可以控制参数,驱动状态机流转,其效果类似于在播放过程中在参数面板实时修改参数。

比如开发可以在请求之后,得到中奖奖品,然后设置状态机参数 winPrize,进而让状态机切换到相应的状态。开发者使用文档见:状态机开发者文档

Preview