上一篇中,我们已经把需要准备好的资源准备好了,现在让我们开始创建动画蓝图吧。这里不打算解释什么是动画蓝图。。请读者自行查阅官方文档。
在创建c++新类中,选择父类为AnimInstance,这个类作为动画蓝图的基类,我们的逻辑将在这个类中实现。命名为HeroAnimInstance。在类中定义两个成员,一个是speed,一个则是direction,并用UPROPERTY进行修饰,为什么要是UPROPERTY呢,主要是为了在动画蓝图的事件模块中使用这些属性,因此需要暴露给蓝图。定义一个函数,用UFUNCTION修饰,该函数负责更新Speed,Direction等等。如下所示:
UPROPERTY(BlueprintReadOnly)
float Speed; // 移动速度
UPROPERTY(BlueprintReadOnly)
float Direction; // 方向(-180~180)
UPROPERTY(BlueprintReadOnly)
bool bInAir; // 是否在空中
UFUNCTION(BlueprintCallable)
void UpdateAnimInfo(float dt);
void UHeroAnimInstance::UpdateAnimInfo(float dt)
{
APawn* Owner = TryGetPawnOwner(); // 得到所属的pawn
ACharacter* Player = Cast<ACharacter>(Owner);
if (Owner != nullptr)
{
Speed = Owner->GetVelocity().Size(); // 获得移动速度
Direction = CalculateDirection(Owner->GetVelocity(), Owner->GetBaseAimRotation()); // 通过速度和旋转计算方向 (-180~180)
bInAir = Player->GetMovementComponent()->IsFalling();
}
}
现在我们已经可以计算得到基本信息,如任务移动的速度及方向,接下来则在新建动画蓝图,选择的父类则是我们创建的c++类,如下图所示:
接着我们在新建的动画蓝图的事件模块,调用我们的UpdateAnimInfo函数,更新Speed和Direction。
接着创建一个BlendSpace1D,因为我们的Hero只有往前跑的动画,没有左右跑,向后跑的动画,因此只需要一个速度用来驱动人物从静止到走,再到跑的即可。如下图所示建立我们的BlendSpace1D。
接下来就进入动画事件图表中,使用状态机来驱动我们的角色。新建状态机,并命名为Locomotion如下图所示:
单击进入Locomotion,并新建如下的节点,连接起来:
在IdleWalkRun中将我们创建的BlendSpace1D混合空间填入,并将Speed作为输入参数,如下图所示:
依次填入剩下的状态机节点。这里只贴出jumpstart,其他的节点一样:
我们已经把所有状态对应的动画序列都已经填充完毕,接着,就是要进行状态间的互相转换。即从静止,或者跑动的状态跳转到jump的状态,如下:
双击上图的红色的那个按钮,进入状态转换发生的条件,显然,从静止状态到jump状态,要用到我们之前的AnimIntsance里的bInAir成员。表示是否已经在空中了。如下图所示,
那么从start到loop状态应该是怎样的条件呢,总不能还是bInAir吧,答案是在快播放完JumpStart动画后则进入loop状态,如下图所示:
在剩余时间小于0.1s时进入loop状态。按上面的状态转换方式,依次填充剩余的转换条件。直到整个状态机的完成。
现在然我们打开之前测试关卡,验证我们的角色是否能够移动,跳跃。
打开ThridPersonCharacter,如下所示,将mesh设置为我们的角色mesh,并把动画蓝图设置为我们之前创建的动画蓝图,如下所示:
设置完毕,点击开始游戏。测试成功!