在前一节实现了自定义CMC中的基础框架,由于下蹲本来就是设定好的一个MoveMode,所以我们不需要在UpdateMove中实现控制逻辑,只需要开放一个接口给外部调用就可以了
下蹲
UFUNCTION(BlueprintCallable)
void CrouchPressed();
void UXCharacterMovementComponent::CrouchPressed()
{
bWantsToCrouch = !bWantsToCrouch;
}
需要注意的是在构造函数中设置可下蹲
NavAgentProps.bCanCrouch = true;
相机的平滑过渡
之前有用过时间轴来平滑过渡相机,当按下按键后进行时间轴播放,现在学习了另外一种做法就是继承CameraManager类,重写UpdateViewTarget方法
//在类中,我们可以判断当前相机是否有我们的Actor,如果没有就不必要执行相机平滑操作了
AAddInCMCCharacter* XCharacter = Cast<AAddInCMCCharacter>(GetOwningPlayerController()->GetPawn());
if (XCharacter)
{
UXCharacterMovementComponent* XMC = XCharacter->GetXCharacterMovementComponent();
//Target
FVector TargetCrouchOffset = FVector(
0.0f,
0.0f,
XMC->CrouchedHalfHeight - XCharacter->GetClass()->GetDefaultObject<ACharacter>()->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() // 设置最终的目标位置
);
//根据当前时间 计算偏移量 CrouchBlendDuration为设定的总下蹲时间
FVector Offset = FMath::Lerp(
FVector::ZeroVector,
TargetCrouchOffset,
FMath::Clamp(CrouchBlendTime / CrouchBlendDuration, 0.0f, 1.0f)
);
if (XMC->IsCrouching())
{
//now frame blendtime 更新下蹲时间
CrouchBlendTime = FMath::Clamp(
CrouchBlendTime + DeltaTime,
0.0f,
CrouchBlendDuration
);
//纠正偏移量,避免最开始相机的突然变换
Offset -= TargetCrouchOffset;
}
else
{
CrouchBlendTime = FMath::Clamp(
CrouchBlendTime - DeltaTime,
0.0f,
CrouchBlendDuration
);
}
if (XMC->IsMovingOnGround())
{
OutVT.POV.Location += Offset; // 应用偏移量
}
}
Offset -= TargetCrouchOffset
的原因在于,如果不减去,Offset的偏移是相对于从idle向蹲下逐渐过渡的,而对于蹲下这个动作是一瞬间的,我们调整的只是摄像机的视觉控制,当蹲下后,Actor身上的弹簧臂就会发送改变,如果不减去,就产生拉扯,而减去后,相当于此时的过渡已经在蹲下后进行表现了,不会出现拉扯感