// 특정 방향 MoveInput으로 이동 Request를 받는다
void UCustomCharacterMovementComponent::RequestPathMove(const FVector& MoveInput)
{
if(IsValid(GetOwner()) == false)
{
return;
}
// 4족인 경우에만 진행
if (bQuadrupedMovement == false)
{
Super::RequestPathMove(MoveInput);
return;
}
FVector AdjustedMoveInput(MoveInput);
const FVector Forward = GetOwner()->GetActorForwardVector();
const FVector Right = GetOwner()->GetActorRightVector();
const FVector2d Right2D { Right.X, Right.Y };
const FVector2D Forward2D { Forward.X, Forward.Y };
FVector2D MoveInput2D { MoveInput.X, MoveInput.Y };
MoveInput2D.Normalize();
const double DotDirectionMoveInput = FVector2d::DotProduct(bMoveBackward ? -Forward2D : Forward2D, MoveInput2D);
// 현재 바라보는 방향(혹은 후면 방향)과 이동 입력의 각도 차이가 11.5도(Acos(0.98)) 이내이면 같은 방향으로 간주
constexpr double MINIMUM_DOT = 0.98;
if(DotDirectionMoveInput > MINIMUM_DOT && bMoveBackward
|| DotDirectionMoveInput < MINIMUM_DOT && bMoveBackward == false)
{
verify(RotationRate.Yaw > UE_KINDA_SMALL_NUMBER);
check(GetWorld());
const float DeltaSeconds = GetWorld()->GetDeltaSeconds();
// 한 프레임 동안 회전할 각도(도 단위)를 계산
float AngleDeg = DeltaSeconds * RotationRate.Yaw;
if (bMoveBackward)
{
// 뒷걸음질할 때는 회전을 조금 더 빨리
constexpr float BACKWARD_ROTATION_MULTIPLIER = 1.5f;
AngleDeg *= BACKWARD_ROTATION_MULTIPLIER;
}
// 좌우 방향 구분
const double DotRightMoveInput = FVector2d::DotProduct(Right2D,MoveInput2D);
if (DotRightMoveInput < 0.0f)
{
AngleDeg *= -1.0;
}
// AngleDeg만큼 돌려준다
AdjustedMoveInput = bMoveBackward
? (-Forward).RotateAngleAxis(AngleDeg, FVector::UpVector)
: Forward.RotateAngleAxis(AngleDeg, FVector::UpVector);
}
Super::RequestPathMove(AdjustedMoveInput);
}