RPC游戏案例【1. 运动动画】

项目配置

UE版本:5.1.1

image-20230424220949881

将工程目录中的 Resources 文件夹里的动画导入到 Characters/RPG_Character/Animations里

image-20230424222325310

接着再创建两个子文件夹,将动画分好类

image-20230424222507869

image-20230424222516133

运动动画

本章工程文件为:RPG_Tutorial_Series_01,如遇问题可下载之后自行对照

预期效果:实现行走、跳跃、蹲伏、倾斜等常见动画效果

混合空间

在Locomotion文件夹下创建一个混合空间1D,命名为Locomotion_BlendSpace1D

image-20230424222658910

打开混合空间,将名称改为Speed,最大值改为500,然后将InPlace、Walk和Run分别拖入时间轴里

你可以按住Ctrl键,然后通过鼠标预览不同的Speed下的不同动画

image-20230424223040930

动画蓝图

创建一个动画蓝图,命名为ABP_RPGCharacter,进入动画蓝图之后,创建一个命名为Locomotion的状态机

行走和奔跑

预期效果:通过方向控制键,角色能够产生位移,同时也会做出相应的动作

配置如下的状态和规则

image-20230424224123397

Idle状态就直接播放Idle动画

image-20230424224138108

Walk/Run状态则是使用上面的混合空间播放器,并创建一个Speed变量来控制

image-20230424224201733

Stop状态也是直接播放Stop动画

image-20230424224234716

从Idle到Walk/Run的规则是根据Speed来判定的

image-20230424224259925

Walk/Run到Stop也是如此

image-20230424224317461

注意,这里外面需要将混合时长设置为0.3,模式设置为立方

image-20230424224901609

Stop到Idle则是自动播放的

image-20230424224358366

这里的混合时长要设置为0.4,模式设为立方

到外层,我们将这个状态机的动作保存到Cache里面,然后再创建一个Main状态机用于输出最终动作

image-20230424224950860

此时Main状态机里面只有一个状态

image-20230424225015701

这个状态里也只用了上面的缓存

image-20230424225037525

接着我们再将角色的运动速度设置为Speed

image-20230424225503864

然后在Pawn里面设置上这个动画蓝图即可

image-20230424225612370

跳跃

预期效果:按下空格键,角色能够跳起来,并且正常回落,同时也会做出相应的动作

打开动画蓝图,进去Main状态机,我们编辑如下的状态和转换规则

image-20230425200642587

注意,Jump和Falling是状态,ToFalling是状态别名

image-20230425200732255

image-20230425201126901

image-20230425201135429

ToFalling到Jump的转换规则如下

IsFalling和Velocity这两个变量都是新创建的

image-20230425200811942

ToFalling到Falling的转换规则如下

只根据IsFalling判断即可

image-20230425200907078

但是要注意,它的优先顺序为2

image-20230425200945278

Jump到Falling的转换规则,就直接基于序列播放器的自动规则就好,也就是说Jump动画播完了就到Falling

image-20230425201050351

上面这部分编辑好之后呢,再创建一个ToLand的状态别名,和一个Land状态

image-20230425201254394

因为Land动画是一个附加动画,所以我们在Land状态里,需要基于Locomotion姿势来播放

image-20230425201347679

image-20230425201407906

ToLand到Land的转换规则,就是IsFalling的取反

image-20230425201449701

Land到Unarmed Locomotion的转换规则,就直接基于序列播放器的自动规则

image-20230425201551983

最后我们再在事件图表里编写一些逻辑,跳跃这部分的动画就算做好了

image-20230425201645715

蹲伏

预期效果:

在游戏里按下左Ctrl键,镜头会拉远,且角色处于蹲伏状态,运动速度降低

再按一次Ctrl键,镜头会拉近,角色恢复直立状态,运动速度也会恢复

首先进入Crouched文件夹内,创建一个混合空间1D

image-20230425205104198

打开这个混合空间,将Crouched_Idle和Courched_Walk放入其中

image-20230425205158169

打开Crouched_Walk,将根运动设置为下面的状态

image-20230425205314436

关于根运动的相关文档可以参考这个链接:

https://docs.unrealengine.com/5.1/zh-CN/root-motion-in-unreal-engine/

进入动画蓝图,我们创建一个新的Crouched状态机,并将这个状态缓存起来

image-20230425205009471

该状态机中只有一个状态

image-20230425205041991

image-20230425205555920

然后进入Main状态机,做如下配置

image-20230425205621688

image-20230425205633394

下面这个IsCrouched变量是新建的

image-20230425205726439

image-20230425205711688

在BP_ThirdPersonCharacter中新建一个Crouched变量,编译保存之后在动画蓝图的事件图表中调用它

image-20230425205916153

接着打开Action文件夹,创建一个IA_Crouched数据资产,可以直接拷贝旁边的IA_Jump,不用做任何改动

image-20230425210005014

image-20230425210014672

然后再IMC_Default中应用它

image-20230425210041351

image-20230425210052584

最后打开BP_ThirdPersonCharacter的事件图表,编写以下蓝图

image-20230425210147332

其中时间轴的配置如下

image-20230425210213482

到此,蹲伏的逻辑就编写完了

但是这样还会跟跳跃动画起冲突,所以还需要优化一下,改成下面这样

image-20230427195343700

角色倾斜

预期效果:在旋转运动方向的时候,角色能根据旋转角度做出相应的侧身动画

在RPG_Character内创建一个Lean文件夹,将原有的MM_Run_Fwd动画复制到文件夹内

image-20230425220510601

复制两份,分别命名为Lean_Left和Lean_Right

首先打开Lean_Left,修改它的附加设置,将Additive动画类型改成网格体控件,基础姿势类型改为选择的动画缩放,然后选择MM_Run_Fwd作为基础姿势动画

image-20230425220727065

再打开左上方的骨骼树一栏,选择pelvis骨骼,向右旋转10度,然后添加关键帧

image-20230425220916699

这样就做好了Lean_Left动画,以此仿照着来做Lean_right动画

附加设置和Lead_Left一样,然后将pelvis骨骼向左旋转10度,然后添加关键帧即可

image-20230425221108877

这两个动画准备好之后,再创建一个混合空间1D

image-20230425221147425

配置如下

image-20230425221218622

接着打开动画蓝图里面,Locomotion状态机里面的 Walk/Run状态,将这个混合空间应用上去

image-20230425221317461

最后在动画蓝图的事件图表里补充上YawDelta的相关逻辑即可

image-20230425221642359

其中DeltaTime是在前面就设置了的

image-20230425221713130

跨栏动画

本章工程文件为:RPG_Tutorial_Series_02,如遇问题可下载之后自行对照

预期效果:当角色面前有障碍物的时候,能按Shift跳过去,并且伴有跨栏动画

image-20230426220132089

实现思路:这里用到了运动扭曲这个插件,我们通过蓝图检测出起跳点,中间点和落脚点,再配合运动扭曲和蒙太奇,来控制动画的播放效果

引用:运动扭曲是一种可以动态调整角色的根骨骼运动以对齐目标的功能。

文档链接:https://docs.unrealengine.com/5.0/zh-CN/motion-warping-in-unreal-engine/

启用插件

image-20230426194828911

导入动画(Resource文件夹内的VaultOver.FBX)

image-20230426195251483

打开动画,启用根运动

image-20230426195424114

蒙太奇

右键此动画,创建一个蒙太奇

在通知轨道里创建三个通知状态

image-20230426195613306

创建完MotionWarping之后,可以按Shift键拉伸到指定帧

将第一个MotionWarping命名为VaultStart

image-20230426220029415

第二个命名为VaultMiddle

image-20230426200603177

第三个命名为VaultLand

image-20230426200546335

计算关键点

打开BP_ThirdPersonCharacter,创建一个Vault函数

该函数的逻辑比较长,我们分段截取

首先检测角色前方是否有障碍物

image-20230426220545819

然后检测障碍物的具体位置

注意,下面的VaultMotionWarp事件暂时还没实现,先不管,我们等这个函数写完就会来实现它

image-20230426220855389

最后计算跨栏过程中的几个关键点

image-20230426220958115

执行跨栏

回到BP_ThirdPersonCharacter的事件图表,编写以下蓝图

逻辑过长,我们还是分段截取

image-20230426221322385

image-20230426221503462

image-20230426221548395

本章逻辑较长,但原理也都比较简单。很容易出错,大家在实现的时候务必注意细节,如果实在不知道自己哪里有问题,可以下载本章工程文件再详细对照一下。

暗杀动画

本章工程文件为:RPG_Tutorial_Series_03,如遇问题可下载之后自行对照

预期效果:到达被害者身后时,按下鼠标左键,能杀死对方,并伴随相应动画

image-20230427214900021

首先导入资源(在工程文件的Resources文件夹下)

image-20230427193759890

这个动画资产是UE4的,所以注意骨骼不要选错了

image-20230427193811041

image-20230427193902722

选中这两个动画,我们重定向到另一个角色身上

image-20230427193953147

image-20230427194051554

打开这两个动画,启用根运动

image-20230427194330441

选中Paired_Knife_Stealth_KidneyAndNeck_Att动画序列,右键创建一个蒙太奇

和之前的跨栏动作一样,,创建一个MotionWarping的通知状态,并做如下配置

image-20230427195645880

然后选择Paired_Knife_Stealth_KidneyAndNeck_Vic动画序列,也是右键创建一个蒙太奇,不需要做额外设置

创建两个输入资产

image-20230427195732002

再在IMC_Default中做如下配置

image-20230427195819218

将之前的跨栏的触发键设置为IA_Vault

image-20230427195959179

受害者

在Blueprints文件夹中,创建一个Character蓝图和一个蓝图接口,分别命名为BP_Dummy和BPI_Assassination

image-20230427212442643

先打开BPI_Assassination接口,我们添加一个函数

这个函数会在发起暗杀的时候,告诉凶手应该站在什么位置,是什么旋转

image-20230427212534131

然后打开受害者,BP_Dummy

点击默认的网格体,将骨骼网格体设置为SKM_Manny_Simple,并选用相应的动画蓝图

image-20230427212657449

并设置自定义碰撞预设

image-20230427213037971

接着复制一份网格体,命名为AssassinREF

将动画模式设置为使用动画资产,将初始位置设置为1,并设置为无碰撞

image-20230427212908095

image-20230427213007589

创建一个球形碰撞器,命名为AssassinationRadius,将它放在受害者的后方

image-20230427213125825

最后创建一个控件组件,命名为AssassinateWidget

在此之前,我们还需要创建一个UI文件夹,然后创建一个控件蓝图(用户控件),命名为WB_AssassinatePrompt

image-20230427213326651

内容也很简单

image-20230427213425008

接着回到BP_Dummy的AssassinateWidget组件,选用上面的这个控件类,并关掉可视

image-20230427213615209

最后设置胶囊体组件的碰撞预设为IgnoreOnlyPawn

image-20230427213712727

接着我们来编写一些逻辑

首先需要继承上面创建的蓝图接口,然后实现这个接口

image-20230427213957896

其中Ragdoll的逻辑在事件图表里,只是做了个延迟,然后启用物理效果

image-20230427214029727

当凶手到达被害者身后时,还需要有个图标展示在被害者头上

image-20230427214314330

凶手

凶手的逻辑就想对简单很多

当按下鼠标左键的时候,就检查碰撞到的Actor是否实现了暗杀接口,如果实现了,就说明可以杀

image-20230427214408975

然后就直接调用接口函数,再执行自己的蒙太奇动画就好了

image-20230427214514388