UE4添加人物动画之状态机
这一节我们创建一个动画蓝图并在C++中把它绑定到角色身上 。
1) 在 UE4 编辑器中,我们以 AnimInstance 为父类创建一个名为 CharacterAnimInstance 的子类。
2) 进入到我们的骨骼网格体文件夹路径,右键选择该资源,创建一个动画蓝图。
3) 双击动画蓝图,点击类设置,然后在右边的细节面板的父类选项中选为我们刚刚创建的 CharacterAnimInstance。
4) 回到 VS 编辑器,在 PlayingCharacter.CPP 文件中添加头文件并把动画的动画蓝图设置成编辑器中创建的动画蓝图。
要添加的头文件:
在构造函数中添加:
5) 打开 CharacterAnimInstance.h 添加两个变量,并把这两个变量公开到蓝图中,让蓝图可以编辑,然后继承 NativeUpdateAnimation 函数,这个函数会每帧更新我们的变量属性。
6) 在CPP文件中添加 PlayingCharacter.h 和 GameFramework/CharacterMovementComponent.h 并实现这些变量。
这一节就到这里,下一节我们会在状态机中使用这些变量并设置动画。
状态机
状态机是可以让动画过渡到另一个动画的工具,它大大简化了动画设计流程。1) 在 UE4 编辑器中,我们以 AnimInstance 为父类创建一个名为 CharacterAnimInstance 的子类。
2) 进入到我们的骨骼网格体文件夹路径,右键选择该资源,创建一个动画蓝图。
3) 双击动画蓝图,点击类设置,然后在右边的细节面板的父类选项中选为我们刚刚创建的 CharacterAnimInstance。
4) 回到 VS 编辑器,在 PlayingCharacter.CPP 文件中添加头文件并把动画的动画蓝图设置成编辑器中创建的动画蓝图。
要添加的头文件:
- #include "ConstructorHelpers.h"
- #include "CharacterAnimInstance.h"
#include "ConstructorHelpers.h" #include "CharacterAnimInstance.h"
在构造函数中添加:
注意,由于我们添加的资源是一个类,所以我们要在资源路径的后面加上_C
。
- //指认动画蓝图
- static ConstructorHelpers::FClassFinder<UCharacterAnimInstance>AnimInstance( TEXT("AnimBlueprint'/Game/TwinSwordAnimsetBase/UE4_Mannequin/Mesh/UE4_Mannequin_Skeleton_AnimBlueprint.UE4_Mannequin_Skeleton_AnimBlueprint_C'") );
- //判断资源是否存在
- if (AnimInstance.Succeeded()) {
- //赋值
- GetMesh()->SetAnimInstanceClass(AnimInstance.Class);
- }
//指认动画蓝图 static ConstructorHelpers::FClassFinder<UCharacterAnimInstance> AnimInstance( TEXT("AnimBlueprint'/Game/TwinSwordAnimsetBase/UE4_Mannequin/Mesh/UE4_Mannequin_Skeleton_AnimBlueprint.UE4_Mannequin_Skeleton_AnimBlueprint_C'") ); //判断资源是否存在 if (AnimInstance.Succeeded()) { //赋值 GetMesh()->SetAnimInstanceClass(AnimInstance.Class); }
5) 打开 CharacterAnimInstance.h 添加两个变量,并把这两个变量公开到蓝图中,让蓝图可以编辑,然后继承 NativeUpdateAnimation 函数,这个函数会每帧更新我们的变量属性。
- /**
- * //角色动画蓝图
- */
- UCLASS()
- classGAMEPROJECT_API UCharacterAnimInstance : public UAnimInstance
- {
- GENERATED_BODY()
- protected:
- virtual void NativeUpdateAnimation(float DeltaSeconds) override;
- //判断人物有没有移动
- UPROPERTY(BlueprintReadOnly)
- float IsMove;
- //判断人物有没有跳跃
- UPROPERTY(BlueprintReadOnly)
- bool IsJump;
- };
/** * //角色动画蓝图 */ UCLASS() class GAMEPROJECT_API UCharacterAnimInstance : public UAnimInstance { GENERATED_BODY() protected: virtual void NativeUpdateAnimation(float DeltaSeconds) override; //判断人物有没有移动 UPROPERTY(BlueprintReadOnly) float IsMove; //判断人物有没有跳跃 UPROPERTY(BlueprintReadOnly) bool IsJump; };
6) 在CPP文件中添加 PlayingCharacter.h 和 GameFramework/CharacterMovementComponent.h 并实现这些变量。
- #include "CharacterAnimInstance.h"
- #include "PlayingCharacter.h"
- #include "GameFramework/CharacterMovementComponent.h"
- void UCharacterAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
- {
- Super::NativeUpdateAnimation(DeltaSeconds);
- //TryGetPawnOwner() 返回的是一个Pawn类,它通过骨骼模型组件返回指认了它的角色,然后再把返回的Pawn转换成我们想要的角色
- APlayingCharacter* Character = Cast<APlayingCharacter>(TryGetPawnOwner());
- if (Character)
- {
- //GetVelocity() 返回的是角色的移动组件的速度,如果这个值大于0说明Character在移动,Size() 是获取向量的模
- IsMove = Character->GetVelocity().Size();
- //IsFalling() 如果角色当前正在下降就返回真
- IsJump = Character->GetCharacterMovement()->IsFalling();
- }
- }
#include "CharacterAnimInstance.h" #include "PlayingCharacter.h" #include "GameFramework/CharacterMovementComponent.h" void UCharacterAnimInstance::NativeUpdateAnimation(float DeltaSeconds) { Super::NativeUpdateAnimation(DeltaSeconds); //TryGetPawnOwner() 返回的是一个Pawn类,它通过骨骼模型组件返回指认了它的角色,然后再把返回的Pawn转换成我们想要的角色 APlayingCharacter* Character = Cast<APlayingCharacter>(TryGetPawnOwner()); if (Character) { //GetVelocity() 返回的是角色的移动组件的速度,如果这个值大于0说明Character在移动,Size() 是获取向量的模 IsMove = Character->GetVelocity().Size(); //IsFalling() 如果角色当前正在下降就返回真 IsJump = Character->GetCharacterMovement()->IsFalling(); } }
这一节就到这里,下一节我们会在状态机中使用这些变量并设置动画。