언리얼엔진3 에서 궤적을 그리며 날아가는 탄알을 구현한 Projectile 의 작동방식에 대해 알아본다.
언리얼엔진3 의 무기 시스템에서 제공하는 공격 메커니즘은 2가지가 있다. Instant 방식과 Projectile 이 그것인데 Instant 는 Fire 와 동시에 충돌판정을 하고 데미지 딜링 처리를 하며, Projectile 은 물리운동을 하며 날아가는 탄알을 소환하고 그것이 직접 충돌 처리 및 데미지딜링을 처리한다.
발사체 종류 를 참조
샘플로 제공되는 UDK 의 Projectile 을 알아본다.
UDK 에서 Projectile 이 Pawn 과 충돌을 계산하는 방식
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 따위를 하지 않아도 되는 장점이 있다.