虚幻引擎_动画蓝图/混合空间/状态机_超详细教学

本课程使用的免费资源:
帕拉贡幽灵https://www.fab.com/listings/17e0840f-8651-4933-bd6d-211a34b1dd17

教学前览:

有这么一个需求: 使用各种动画资产, 构建一个角色的动画蓝图, 在这个蓝图中,我们需要组织调用角色的前, 后, 左, 右, 移动, 跳跃, 各种基本动画资产, 然后实现的效果: 角色挂载这个动画蓝图后, 可以实现角色的前, 后, 左, 右, 移动, 跳跃;

我们需要:

  1. 理解:什么是动画资产,什么是动画蓝图, 动画蓝图为什么可以组织调度动画资产...
  2. 掌握蓝图的基础用法和动画资源的基本特性
  3. 从0开始搭建一个混合空间用来高效调度动画资产
  4. 用状态机根据角色的各种状态切换不同的动作

一. 虚幻引擎中角色动效的核心组件:

  • Skeleton(骨骼) 相当于人体的骨架:是一套 "关节结构标准",规定了角色有哪些关节(比如肩、肘、膝盖)、关节怎么连接。它是后续所有动画、模型绑定的 "基础模板"。

  • Skeleton Mesh(骨骼网格体) 相当于人体的皮肤 + 肌肉:是角色的可视化模型(比如人物的身体、衣服)。它必须 "绑定" 到 Skeleton 上(这个过程叫 "蒙皮"),这样骨骼动的时候,Mesh 才会跟着变形(比如胳膊肘弯,手臂模型也会弯)。

  • Animation(动画) 相当于人体的动作数据:比如 "走路""跑步""跳跃" 这些具体动作,是基于 Skeleton 的关节做的(比如让膝盖关节弯曲来做抬腿动作)。所以 Animation 必须和 Skeleton 的关节结构对应,否则没法用在对应的角色上。

  • Animation Blueprint(动画蓝图) 相当于控制动作的 "大脑":是用来管理 Animation 的逻辑容器。比如判断 "角色移动速度快就播跑步动画、速度慢就播走路动画",还能实现动画混合(比如边走路边挥手)。它会调用前面的 Animation,最终让绑定在 Skeleton 上的 Mesh "动起来"。

动画蓝图 (ABP) > 状态机 (State Machine) > 混合空间 (Blend Space)


二. 它们的依赖关系(流程)

Skeleton(核心基础) → 绑定 Mesh(可视化模型)``Skeleton → 制作 Animation(动作数据)``Animation → 被 Animation Blueprint(逻辑控制器) 调用

最终:Animation Blueprint 驱动 Skeleton,带动 Mesh 呈现出动态效果
注意: Animation Blueprint驱动``Skeleton的逻辑由其自身完成, 但是如何调用这些逻辑去驱动动画,是由C++程序完成的

三. 动画蓝图

1. 创建并使用动画蓝图:

创建动画蓝图:

新建一个Animation文件夹, 存放动画蓝图, 创建一个动画蓝图;

选择幽灵骨骼,命名为ABP_ShooterCharacter

在角色中调用动画蓝图:

进入你需要管理的角色蓝图中, 修改其动画模式, 选择使用动画蓝图, 然后选择我们的动画类: ABP_ShooterCharacter

2. 动画蓝图的基本操作:

加入资源

这是最终输出点, 右下角的资产浏览器里面搜索你需要的动画资源, 可以拖入场景中

删除节点之间的线:

按住Alt键点任意一端的小人就可以了

删除节点:

单独删除: 直接左键点击, 然后按Del

删除一堆: 左键长按滑动, 可以选中一堆

设置循环动画:

设置双路混合节点:

右击空白处, 搜索Two Way Blend

Alpha变量用于控制混合程度, 为0时仅播放A动画, 为1时仅播B, 0.5时等比例播放

添加变量:

Alpha值可以创建一个变量单独控制, 这样每次更改无需重新编译;

坐下角窗口面板添加变量命名为Speed

然后拖到场景中创建:

编译后在右下角调节Speed

四. 混合空间

在移动系统中: 你不仅需要"走"和"跑"两个状态,你还需要"左走"、"右走"、"左前跑"、"右后跑"等几十个状态。这些状态之间的连线(Transition)会变得像蜘蛛网一样极其复杂,难以维护。

所以我们使用混合空间, 它能让我们用二维的方式管理动画单元, 移动空间是组织调度管理蓝图资产的高效手段;

创建混合空间:

选好骨骼类型后,命名为: BS_Locomation (举例,命名随你)

混合空间使用方式:

在Axis Setting里面定义坐标名, 然后设置取值范围, 然后在坐标轴上, 横轴角度代表角色朝向, 竖轴速度代表角色移速, 任何一个点,都对应着一个玩家二维状态信息, 都可以为此状态玩家设置一个动画单元, 例如: 在速度为0时, 应该为角色添加待机状态, 搜索资源然后拖出来, 按Shift吸附到网格上;两个节点之间按Ctrl可以实时预览

节点之间的连线是引擎自动生成的 "混合权重计算路径"------ 当你的角色参数(比如 Speed 从 0 涨到 100)落在这条连线上 / 附近时,引擎会根据参数到两个采样点的距离,自动分配这两个动画的 "混合权重":

  • 比如参数接近底部点(Speed≈0):"站立动画" 的权重占比高,"走路动画" 占比低;
  • 参数接近橙色点(Speed≈100):"走路动画" 占比高,"站立动画" 占比低;
  • 参数在连线中间(比如 Speed=50):两个动画各占一部分权重,最终呈现的是 "站立→走路" 的过渡动作(不会硬切)。

完整的混合空间for move system:

调用混合空间:

在资产浏览器里拖出来, 用两个参数来控制它, 连接到输出口

目前我们可以自己在右下角的动画预览编辑器, 通过调节Angle和Speed的值来控制动画, 但是实际上在游戏里, 我们需要用角色的速度和转向角来作为输入, 去驱动BS_Locomation;

想要达成这个功能, 通常我们会选择使用事件蓝图来实现, 即使我们可以用C++实现(不推荐)

五. 事件图表(初级):

事件图表是一个动画系统的工具, 用来快速获取游戏角色的状态以及其他数据或者逻辑的工具;

在上面的动画蓝图中, 我们需要用角色的速度和转向角来作为输入, 去驱动BS_Locomation;

但是我们该如何获取到角色的实际数据呢?

想要达成这个功能, 通常我们会选择使用事件蓝图来实现, 即使我们可以用C++实现(不推荐)

1.理解基础的节点功能:

节点的接口有的是传值的, 有的是只进行执行(激活)的;

这种圆的接头是传值的, 不同颜色代表不同数据类型; 五边方型的接头是传递执行信号的;

节点:Event Blueprint Update Animation(蓝图更新动画事件)

它是干嘛的? 这是动画蓝图里的"心脏"。游戏运行后,它会**每帧(每一秒几十次)**不停地跳动。

为什么是灰色的(提示已禁用)?

UE 为了节省资源,如果你没有在这个节点后面连任何线,它就会自动进入"休眠"状态。

Delta Time X :这是两帧之间的时间差。新手暂时可以不用管它,它是给高级运算(如平滑过渡)准备的。

节点:Try Get Pawn Owner(尝试获取 Pawn 所有者)

作用: 返回此动画蓝图的使用者。

动画蓝图只是衣服(外壳),它必须穿在某个角色(Pawn/Character)身上。

这个节点的作用就是:"告诉我,是谁在穿这件衣服?"

返回值 (Return Value):

它会吐出一个"对象"。这个对象就是使用此动画蓝图的角色

节点:Is Valid (判空指针)

获取到角色指针后必须判空, 就和C++的if()判断一样

节点: SET (为变量设置数值float Speed = ?;)

获取角色的速度向量(速率和方向):

把Speed变量拖入空间, 然后选择设置Speed, 然后链接角色指针(判空后的), 如果发现指针非空, 就会执行SET速率Speed变量的操作, 然后就可以尝试一次读取速度的操作;

这里会尝试读取速率Speed, 但是读不到值, 因为还没传值进来, 白线是执行线, 我们需要绿线来传值进来;

节点: Get Velocity (获取速度向量=速度大小+速度方向)

节点: Vector Length (向量转标量)

不同数值接口颜色代表着不同数据类型, 这里是速度向量转为速度大小

最终效果:

节点: Inverse Transform Direction(逆向变换方向)

作用是:把"世界的方向"转变成"角色的主观方向"。

想象一下这个场景:

世界坐标: 地图的北方永远是固定不变的。

角色坐标: 角色的"前方"是随着角色转身而改变的。

问题来了: 游戏知道角色正在向"世界地图的北方"移动,但如果你不告诉 UE,UE 就不知道角色是在向前走、向后退还是向左侧滑。

如果角色面向北方走,那是"向前走"。

如果角色面向南方走,那是"向后退"。

如果角色面向东方走,那是"向左侧滑"。

Inverse Transform Direction 的工作就是: 拿着"世界速度方向",对比"角色面对的方向",最后吐出一个结果------"噢!原来角色正在往他自己的左边走!"

节点:获取玩家变换

它是用来获取一个物体在 3D 世界里的全方位状态信息 的。

Target(蓝色引脚):

含义: "目标",也就是"你想看谁的户口本?"。

通常连什么: 在动画蓝图里,这里通常连你之前看到的那个 Try Get Pawn Owner(也就是获取你的角色)。这表示:"我要获取我这个角色的位置和旋转信息。"

Return Value(橙色引脚):

含义: 返回的"变换"数据。

  1. Location(位置): 这个物体在地图上的具体坐标(X, Y, Z)。

  2. Rotation(旋转): 这个物体正对着哪个方向,斜了多少度。

  3. Scale(缩放): 这个物体有多大,有没有被拉长或缩放。

节点: Rotation From X Vector(根据 X 向量生成旋转)

在虚幻引擎里,默认规定 X 轴是物体的"正前方"(也就是物体的鼻子或脸)。

这个节点的作用是:"如果我要让我的正面(X轴)对着这个方向,我该旋转多少度?"

可以展开:

最终效果:

六. 状态机的使用方式:

  • AnimGraph(总指挥部):就是你现在看到的这个大窗口。

  • State Machine(状态机/导演):你可以在这里放一个状态机。

  • State(状态/演员):比如你有一个"移动中"的状态。

  • Blendspace(混合空间/表演细节) :你会双击进入"移动中"这个状态,然后把这张图里的 BS_Locomotion 逻辑放进去。

动画蓝图 (ABP) > 状态机 (State Machine) > 混合空间 (Blend Space)

混合空间是对动画资产的排列组合和调用; 状态机是混合空间的调用者, 其状态节点就是对混合空间或动画蓝图的封装, 然后由状态机统一调度状态节点, 最后多个状态机之间的协作, 被统一成为一个动画蓝图, 所有的动画资产会根据这个蓝图调度

基础操作:

创建状态机:

添加状态节点:

右击空白处, 选择添加状态, 我这里命名为Grounded

点击此处退回到动画图表

设置状态节点

为状态机的状态节点添加动画, 这里以Grounded为例:

点击Grounded进入节点, 进入后, 会有一个Output Animation Pose, 这个东西本质上和之前做动画蓝图一样的, 连好线路后最终从这里输出:

我们直接把之前写的移动动作逻辑放入状态机中

设置状态切换:

我们实现这样一个功能:从地面跳到空中, 再从空中落到地面
地->空:

新建一个Airborne空中状态, 然后链接两个状态, 然后可以点击这个圆形,进入切换状态规则的设置

Result的红色引脚代表着, 期待一个bool类型, 如果是真则会触发切换

我们可以创建一个IsAirborne的bool变量链接它;

空->地:

从Airborne画一根线到Grounded

进入切换规则节点后: 添加逻辑!运算符节点, 用于取反IsAirborne变量


七. 事件图表(进阶):

节点: sequence (信号拆分)

这个节点的作用是:把一个触发信号拆分成多路,按从上到下的顺序依次执行一连串动作。
为什么需要它?

在 UE 蓝图里,一个白色箭头通常只能引出一根线。如果你想在"游戏开始"时同时做三件事(比如:1.给玩家加血;2.刷出怪物;3.播放音乐),你就需要用 Sequence 节点把这一路信号分成 Then 0、Then 1、Then 2 来按顺序完成。

节点: Try Get Pawn Owner

节点: Get Movement Component

节点: Is Falling

最终效果:

八. 状态机(进阶):

Locomation优化跳跃过程:

在地面和空中的两个阶段上多加几个过渡动画:

动画过渡优化:

状态节点之间的动画过渡也可以在 "状态切换节点" 的细节面板修改:

九. 叠加动画

叠加动画(Additive Animation)就是"在原有动作的基础上,额外增加一层微调动作",且不破坏原本的动作。

核心公式:最终效果 = 基础动作 + 叠加动作

基础动作(Base Pose): 就像你的全身衣服。比如你正在"跑步",你的全身骨骼(腿、胳膊、躯干)都在为了跑步而摆动。

叠加动作(Additive): 就像你戴的一根围巾一个发卡。它不管你是在跑步、坐着还是跳跃,它只负责在那儿产生一点额外的位移或晃动。

为什么要用"叠加",而不是直接做个新动作?

假设你正在做一个射击游戏,你希望角色在任何状态下都能有"呼吸"的效果(胸腔起伏)。

笨办法(不用叠加):

你需要专门制作"站立+呼吸"、"走路+呼吸"、"跑步+呼吸"、"蹲下+呼吸"......这会导致动画文件数量爆炸,工作量极大。

聪明办法(叠加动画):

你只做一个纯粹的、极短的**"胸腔起伏"**动画(这个动画里只有胸部骨骼在动)。

告诉 UE:把这个呼吸的"起伏"叠加到任何正在播放的动作上去。

结果: 无论角色是在跑、在跳还是在趴着,他都会自然地呼吸了。

它在技术上是怎么实现的?(数学原理)

这是叠加动画最神奇的地方:它存的不是"位置",而是"差值"。

普通动画(绝对动画): 记录的是"手现在必须在坐标 (10, 10)"。如果你播放它,手会强制跳到那个位置,不管之前在干嘛。

叠加动画(相对动画): 记录的是"手在当前位置的基础上,往上抬 5 厘米"。

如果手原本在腰部,播放叠加动画后,手会抬到腰部上方 5 厘米。

如果手原本在头顶,播放叠加动画后,手会抬到头顶上方 5 厘米。


常见的 3 个使用场景

  1. 呼吸/颤抖: 为各种静态或动态动作增加一点生动的细节。

  2. 受击反馈(Hit Reaction): 角色正在跑步,突然肩膀中了一弹。你可以把"肩膀猛震一下"的叠加动画加进去,这样角色会一边跑一边肩膀晃动,而不会打断跑步的脚步。

  3. 瞄准偏移(Aim Offset): 角色身体在往前跑,但手里的枪要随着玩家的鼠标上下左右转动。这个枪口的"上下左右偏移"就是叠加在跑步动作之上的。

如何使用叠加动画:

把Idle_AO_Combat添加到动画图表中:

然后在暴露出的接口中, Yaw表示偏航角, 我们已经在之前的Locomation中设置好了关于Yaw的动画,所以无需理会; Pitch表示仰角, 我们还没设置, 好在我们有叠加动画, 所以我们只需创建一个变量节点Aim Pitch给Pitch引脚传值就行了,然后在事件图表中将游戏角色的数据传入Pitch依赖的变量节点Aim Pitch;

事件图表中为Aim Pitch赋值

每个节点的功能:

Try Get Pawn Owner(尝试获取 Pawn 所有者)

功能:找到这个动画蓝图正穿在哪个角色身上。

Get Control Rotation(获取控制器旋转)

功能 :获取玩家相机(或者说控制器)在世界中指向的角度。

重点:这是玩家"眼睛"看的地方。当你动鼠标上下左右看时,这个值就在变。

Get Actor Rotation(获取 Actor 旋转)

功能 :获取角色身体在世界中面朝的角度。

重点:这是角色"胸膛"正对的方向。

Delta (Rotator)(旋转差值)

功能 :做减法。计算两个角度之间的差距

计算公式:A (控制旋转) - B (身体旋转) = 相对角度。

SET Aim Pitch

功能 :把算出来的结果里的 Pitch(俯仰角,即上下看的高度) 存到一个变量里,给后面的动画用。

为什么要用 Control Rotation 减去 Actor Rotation?

这是新手最容易困惑的地方。我们为什么要相减?

核心原因:获取符合动画蓝图范围的pitch

动画蓝图设计动画和pitch取值关系是是:

向上看 pitch = 0 ->90;向下看 pitch = 0 -> -90;

因为如果我们不减Actor Rotation,在默认情况下:

向上看Control Rotation返回的pitch值是0->90,向下看的pitch值是360->270而不是0->-90;

也许你还会有疑问, 既然一开始玩家朝向是0, 那你向下转90度, 用Control Rotation - Actor Rotation, 得到的应该是270 - 0 = 270;

Delta 节点的黑科技:

它是专门设计来对付这个问题的。当你用 A (350度) 减去 B (0度) 时:

  • 普通的减法结果是 350。

  • 但 Delta (Rotator) 节点很聪明,它知道你其实是在问"最短距离"。它会意识到 350 度其实就是 -10 度,所以它给你的返回结果会是 -10

所以,即便 Get Control Rotation 给你的是 270-360,经过 Delta 节点计算后,你拿到的 Aim Pitch 依然会是正确的 -90 到 0。

这段逻辑最终实现了什么?

这段逻辑通常是为 瞄准偏移 (Aim Offset) 服务的:

  • Aim Pitch (Y 轴):存下这个值后,你会把它连到动画图表的混合空间里。

  • 效果 :当玩家鼠标向上推 时,Aim Pitch 变大,角色的脊椎骨骼就会带动枪口向上抬 ;当玩家鼠标向下拽 时,枪口向下压

九. 动画蓝图总览

动画蓝图 = AnimGraph(动画图表) + EventGraph(事件图表)

事件图表总览:

动画蓝图总览:

动画蓝图的Locomation状态机总览:

Grounded状态节点:
Jumpping状态节点:
Airborne状态节点:
Landing状态节点:
相关推荐
_风华ts2 小时前
UObject复制与RPC
网络·c++·网络协议·rpc·虚幻
qianbo_insist4 小时前
unity 无头模式启动
unity·游戏引擎
weixin_409383125 小时前
cocos shader闪光
游戏引擎·cocos2d
Howrun7775 小时前
虚幻引擎_用户小控件_准星
c++·游戏引擎·虚幻
孟无岐21 小时前
【Laya】Component 使用说明
typescript·游戏引擎·游戏程序·laya
weixin_4093831221 小时前
cocos shader三角流光
游戏引擎·cocos2d
Mars-xq1 天前
godot 毛玻璃效果着色器shader
游戏引擎·godot·着色器
绀目澄清1 天前
Unity 的AI Navigation 系统详细总结
人工智能·unity·游戏引擎
绀目澄清1 天前
Unity3D AI Navigation 详解:从基础概念到实战应用
unity·游戏引擎