如何使用C++来处理角色的动画蓝图呢?
基于AnimInstance类创建一个属于自己的动画实例,对于角色动画状态机的实现和切换部分还是使用编辑器中的动画图表和事件图表,只不过,在实际的使用变量操控播放动画时,使用C++的部分来控制。
状态机动画图表:
创建完属于自己的C++类,在动画蓝图的类设置里面将父类设置成自己创建的C++类。
.h代码
public:
virtual void NativeInitializeAnimation() override;
UFUNCTION(BlueprintCallable,Category = "Animation Properties")
void UpdateAnimationProperties();
private:
UPROPERTY(BlueprintReadOnly,Category = "Animation Properties",meta = (AllowPrivateAccess = "true"))
float Speed;//速度
UPROPERTY(BlueprintReadOnly, Category = "Animation Properties", meta = (AllowPrivateAccess = "true"))
float Direction;//方向
UPROPERTY(BlueprintReadOnly, Category = "Animation Properties", meta = (AllowPrivateAccess = "true"))
bool EnableJump;//是否能够跳跃
UPROPERTY(BlueprintReadOnly, Category = "Animation Properties", meta = (AllowPrivateAccess = "true"))
bool Crouching;//是否蹲下
UPROPERTY(BlueprintReadOnly, Category = "Animation Properties", meta = (AllowPrivateAccess = "true"))
ASGCharacter* PlayerRef;//角色引用
NativeInitializeAnimation函数是父类的虚函数,可以进行重写,在这个函数里面进行属性初始化。
UpdateAnimationProperties这个方法是在蓝图中使用,让其去不断更新获取最新的变量的值。
.cpp代码
#include "Animation/CharacterAnimInstance.h"
#include "Gameplay/SGCharacter.h"
#include "GameFramework/PawnMovementComponent.h"
void UCharacterAnimInstance::NativeInitializeAnimation()
{
PlayerRef = Cast<ASGCharacter>(TryGetPawnOwner());
}
void UCharacterAnimInstance::UpdateAnimationProperties()
{
if(!PlayerRef)
{
PlayerRef = Cast<ASGCharacter>(TryGetPawnOwner());
}
if (PlayerRef)
{
const FVector SpeedVector = PlayerRef->GetVelocity();
const FVector NewVector = FVector(SpeedVector.X, SpeedVector.Y, 0);
Speed = NewVector.Size();
Direction = CalculateDirection(SpeedVector, PlayerRef->GetActorRotation());
EnableJump = PlayerRef->GetMovementComponent()->IsFalling();
Crouching = PlayerRef->GetMovementComponent()->IsCrouching();
}
}
?此时会不断去更新变量里面的值,而在C++中声明的变量,则是去控制状态机的状态变化。
?比如这个跳跃的判断,满足这些条件就会去改变角色的状态,进而切换对应的动画。
注:
除了在蓝图中去更新变量,还有一个C++方法,也是去不断更新。
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
但是要注意这个方法是在编辑状态下也会执行,有可能在为动画蓝图设置自己的父类的时候,编辑器崩溃,可以使用预编译指令WITH_EDITOR,否则也会警告太多。
|