首先我们要在编辑器中创建我们的C++文件
创建完成后,我们对原生的初始化动画进行重写,对原生的动画进行更新。
virtual void NativeInitializeAnimation() override;//对原生的初始化动画进行重写
virtual void NativeUpdateAnimation(float DeltaSeconds) override;//对原生的动画进行更新
给新的动画蓝图实例提供变量:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Reference", meta = (AllowPrivateAccess = "true"))
float GroundSpeed;
void GetGroundSpeed();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Reference", meta = (AllowPrivateAccess = "true"))
float AirSpeed;
void GetAirSpeed();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Reference", meta = (AllowPrivateAccess = "true"))
bool bShouldMove;
void GetShouldMove();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Reference", meta = (AllowPrivateAccess = "true"))
bool bIsFalling;
void GetIsFalling();
void UCharacterAnimInstance::NativeInitializeAnimation()
{
Super::NativeInitializeAnimation();
//获取人物
ClimbingSystemCharacter = Cast<AClimbingSystemCharacter>(TryGetPawnOwner());
if (ClimbingSystemCharacter)//判断人物是否被获取
{
CustomMovementComponent = ClimbingSystemCharacter->GetCustomMovementComponent();
if (CustomMovementComponent == nullptr)
{
Debug::Print("movement component is null");
}
}
}
void UCharacterAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
if (!ClimbingSystemCharacter || !CustomMovementComponent) return;
GetGroundSpeed();
GetAirSpeed();
GetShouldMove();
GetIsFalling();
GetIsClimbing();
GetClimbVelocity();
}
void UCharacterAnimInstance::GetGroundSpeed()
{
GroundSpeed = UKismetMathLibrary::VSizeXY(ClimbingSystemCharacter->GetVelocity());
}
void UCharacterAnimInstance::GetAirSpeed()
{
AirSpeed = ClimbingSystemCharacter->GetVelocity().Z;
}
void UCharacterAnimInstance::GetShouldMove()
{
bShouldMove =(CustomMovementComponent->GetCurrentAcceleration().Size() > 0) &&GroundSpeed > 5.f &&!bIsFalling;
//判断加速度是否大于0,地面速度是否大于5,是否为落地模式
}
void UCharacterAnimInstance::GetIsFalling()
{
bIsFalling = CustomMovementComponent->IsFalling();
}
之后回到编译器,将写好的实例创建出来。将创建好的动画蓝图赋予人物身上。
在状态机中调整我们实现动作的条件
动态机完成后,我们在回到代码,创建动画实例和,通过动画实例来调用蒙太奇
void PlayClimbMontage(UAnimMontage* MontageToPlay);//调用蒙太奇函数
UFUNCTION()
void OnClimbMontageEnded(UAnimMontage* Montage, bool bInterrupted);
UPROPERTY()
class UAnimInstance* OwningPlayerAnimInstance;//创建播放器实例
UPROPERTY()
class AClimbingSystemCharacter* OwningPlayerCharacter;
void UCustomMovementComponent::PlayClimbMontage(UAnimMontage* MontageToPlay)
{
if (!MontageToPlay)
{
Debug::Print(TEXT("Montage is NULL"));
return;
}
if (!OwningPlayerAnimInstance)
{
Debug::Print(TEXT("Anim Instance is NULL"));
return;
}
if (OwningPlayerAnimInstance->IsAnyMontagePlaying())//如果有任意的montage在运行,也会返回退出
{
Debug::Print(TEXT("Other Montage is Playing"));
return;
}
Debug::Print(TEXT("PlayMontage"));
OwningPlayerAnimInstance->Montage_Play(MontageToPlay);
}
void UCustomMovementComponent::OnClimbMontageEnded(UAnimMontage* Montage, bool bInterrupted)
{
if (Montage == IdleToClimbMontage || Montage == ClimbDownLedgeMontage)
{
StartClimbing();
StopMovementImmediately();
}
if(Montage == ClimbToTopMontage || Montage == ValueMontage)
{
SetMovementMode(MOVE_Walking);
}
Debug::Print(TEXT("Climb Montage Ended"));
}
void UCustomMovementComponent::BeginPlay()
{
// Call the base class
Super::BeginPlay();
OwningPlayerAnimInstance = CharacterOwner->GetMesh()->GetAnimInstance();//获取动画实例
if (OwningPlayerAnimInstance)
{
OwningPlayerAnimInstance->OnMontageEnded.AddDynamic(this, &UCustomMovementComponent::OnClimbMontageEnded);
OwningPlayerAnimInstance->OnMontageBlendingOut.AddDynamic(this, &UCustomMovementComponent::OnClimbMontageEnded);
}
OwningPlayerCharacter = Cast<AClimbingSystemCharacter>(CharacterOwner);
}