Projectile 처리 방식

언리얼엔진3 에서 궤적을 그리며 날아가는 탄알을 구현한 Projectile 의 작동방식에 대해 알아본다.

특징

언리얼엔진3 의 무기 시스템에서 제공하는 공격 메커니즘은 2가지가 있다. Instant 방식과 Projectile 이 그것인데 Instant 는 Fire 와 동시에 충돌판정을 하고 데미지 딜링 처리를 하며, Projectile 은 물리운동을 하며 날아가는 탄알을 소환하고 그것이 직접 충돌 처리 및 데미지딜링을 처리한다.

발사체 종류 를 참조

UDK Projectile

샘플로 제공되는 UDK 의 Projectile 을 알아본다.

충돌처리

UDK 에서 Projectile 이 Pawn 과 충돌을 계산하는 방식

UDKWeapon.cpp
void AUDKProjectile::TickSpecial( FLOAT DeltaSeconds )
{
    ...
 
    // 특정 Sphere 내에 있는 모든 Pawn 들의 리스트를 얻어온다.
    FCheckResult* Link = GWorld->Hash->PawnOverlapCheck( GMainThreadMemStack, this, Location, CheckRadius * PlatformMultiplier );
 
    // 획득한 Pawn 들의 루프를 돌며
    foreach Link
 
    // Pawn 의 충돌실린더의 높이과 탄알의 높이를 비교하여 1차 비교를 하고
    if ( Abs( Location.Z - TargetPawn->Location.Z ) > TargetPawn->CylinderComponent->CollisionHeight + EffectiveRadius )
    {
        bDoTouch = FALSE;
    }
    else
    {
        // XY 평면에 대해 점과 선분간 거리체크를 통해 Projectile 이 Pawn 과 충돌하였는지 체크한다.
        FVector ClosestPoint;
        PointDistToLine( TargetPawn->Location, Velocity, Location, ClosestPoint );
        bDoTouch = ( ClosestPoint - TargetPawn->Location ).Size2D() < TargetPawn->CylinderComponent->CollisionRadius - EffectiveRadius;
    }
 
    // 충돌했다면 Projectile 에 Touch 이벤트를 보낸다.
    if ( bDoTouch )
    {
        eventTouch( TargetPawn, TargetPawn->CylinderComponent, Location, ( Location - TargetPawn->Location ).SafeNormal() );
        break;
    }
}

굉장히 간략화된 충돌처리 방식이다. 정밀한 충돌처리가 필요없다면 이 방식도 고려해볼만 하다.

일정 범위내 Pawn 의 리스트를 얻어와 Projectile 과 거리계산을 한다. 이때 비교는 각자의 Location 으로 하기 때문에 고비용의 SingleLineCheck 따위를 하지 않아도 되는 장점이 있다.