여러가지 몬스터를 만들던 중, 다이너마이트를 던지는 적을 만들고자 하였다.
해당 적은 플레이어와 일정한 거리 이하가 되면 플레이어를 향해 다이너마이트를 던진다.
다이너마이트는 포물선을 그리며 날아가야하고, 플레이어가 가까이 붙이면 가까이, 멀리 있다면 멀리 던져야 한다.
void ADynamite::LaunchTowardsPlayer()
{
AActor* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if (Player) {
FVector PlayerLocation = Player->GetActorLocation();
FVector LaunchDirection = (PlayerLocation - GetActorLocation()).GetSafeNormal();
float distance = FVector::Dist(PlayerLocation, GetActorLocation());
float launchSpeed = CalculateLaunchSpeed(distance);
FVector LaunchVelocity = LaunchDirection * launchSpeed;
LaunchVelocity.Z = CalculateLaunchZVelocity(distance, launchSpeed);
ProjectileMovement->Velocity = LaunchVelocity;
}
}
플레이어의 위치에서 폭탄의 위치를 빼서 방향벡터를 구하고, 이를 정규화하여 단위벡터를 구한다.
플레이어와의 거리를 토대로 발사속도를 계산하고, 이렇게 구해진 두 값으로 ProjectileMovement의 Velocity값을 구한다.
이때 Z값은 발사체의 수직속도를 나타내는데, 포물선을 그리며 날아가는 폭탄을 구현하기 위해 이전에 구한 발사속도 값을 사용해서 수직속도도 구해주었다.
const float MinSpeed = 500.0f;
const float MaxSpeed = 1000.0f;
return FMath::Clamp(distance * 0.6f, MinSpeed, MaxSpeed);
발사속도는 플레이어와의 거리값을 Clamp하여 구한다.
너무 낮거나 눞지않도록 최소값과 최대값을 정해두고 반환하도록 한다.
float ADynamite::CalculateLaunchZVelocity(float launchSpeed)
{
const float Angle = 45.0f;
return launchSpeed * FMath::Sin(FMath::DegreesToRadians(Angle));
}
수직속도는 포물선 운동에서 나오는 y축 속도를 계산하는 공식이다.
포물선을 그리기 위해 발사각도를 45도로 하고, 이를 라디안으로 변환한다.
Sin(45도)에 발사속도를 곱하면 수직속도를 구할 수 있게 된다.