2014. 5. 21.

UE4 에서의 대미지

글쓴이 * Jeff Farris

"누군가에게 상처를 입혀야 할 경우에는 상대방의 복수를 두려워할 필요가 없을 정도로 철저하게 짓밟아야 한다."
-니콜로 마키아벨리

"Damage" (대미지)란 게임에서 자주 쓰이는 개념으로, UE4 게임 프레임워크에 포함시킨 대미지 함수성에 대해 간단한 입문서를 제공해 드리고자 합니다.

대미지는 베이스 Actor 클래스에 지원되는 기능이므로, 폭넓게 사용 가능합니다. 이 시스템은 자주 쓰이는 함수성을 쉽게 접근할 수 있도록 해 주어 빠른 결과 확인이 가능하면서도, 확장이 가능하여 필요에 따른 대미지 모델 커스터마이징이 가능합니다. 또한 대미지에 어떻게 반응할지 가정을 해야 하는 상황을 피할 수 있도록 노력을 기울였습니다. 즉 엔진에서 'hit point' (생명력)이나 'death' (사망)같은 개념을 찾을 수 없게 되었습니다. 이는 특정 게임에 국한된 개념이기에, 일반화시키려 해 봐야 결국 득보다 실이 많았기 때문입니다.

기본적인 대미지 관련 개념

대미지에 대해 이야기할 때 자주 사용되는 개념을 몇 가지 간단히 다루고자 합니다.

DamageType

이름에서 알 수 있듯이, DamageType (대미지 타입)은 대미지의 근원지와 무관하게 "유형"을 설명하는 데 사용되는 오브젝트입니다. 대미지 근원지가 많고 그 사이에 공통된 함수성이 있었으면 하는 경우 매우 유용한 개념입니다.

이를 쉽게 설명하는 예로 화염 대미지를 들 수 있습니다. 화염 대미지를 입을 때마다 "앗뜨거" 라 외치면서 근처의 물가로 달려가도록 한다고 칩시다. 이러한 행위에 대한 코드를 플레이어를 태울 수 있는 모든 액터( 혹은 탈 수 있는 모든 액터 유형)에 복제하기 보다는, 화염에 대한 대미지 유형(UDamageTypeFire)을 정의한 다음, 거기에 일정 유형의 HandleDamagedCharacter() 함수를 주고, TakeDamage() 호출 체인에서 적절히 호출해 주면 됩니다.

Instigator

Instigator (인스티게이터)는 누가 대미지를 입혔는가, 전형적으로 PlayerController 또는 AIController 가 됩니다. 화염 대미지의 경우, 플레이어 또는 불을 지른 AI 가 될 것입니다.

DamageCauser

"causer" (유발자)는 보통 무엇이 대미지를 입혔는가, 이를테면 방금 걸어지나간 ACampFire (캠프 파이어) 액터같은 것입니다.

C++ 에서의 대미지

먼저 네이티브 코드에서의 대미지 지원을 살펴봅시다.

이 경우, 액터에 대미지를 입히는 것은 간단합니다. 그냥 거기서 TakeDamage() 를 호출해 주면 됩니다.

virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser);

마찬가지로 대미지에 반응하기 위해, 받는 액터에서 TakeDamage() 를 덮어써서 별도의 처리 코드를 삽입해 주기만 하면 됩니다. 쉽지요!

TakeDamage() 호출시 DamageEvent 를 파라미터로 받는 것이 보일 것입니다. 이 FDamageEvent 데이터 구조체에는 반응 코드가 적절히 대응할 수 있도록 대미지를 입히는 이벤트의 구체적인 상황에 대한 데이터가 들어갑니다. UE4 에는 세 가지 형태의 대미지 이벤트가 내장되어 있습니다.

FPointDamageEvent

"요 방향에서 맞았더니 얼굴 딱 이 부분이 따갑네요."

점 대미지 이벤트는 총알이나 펀치처럼 피해자의 특정 지점에 가해진 대미지를 모델링하는 것입니다. 맞은 방향, 표면 충격을 나타내는 FHitResult 도 들어있습니다.

FRadialDamageEvent

"저쪽의 대폭발때문에 온몸 왼쪽이 쑤시네요."

방사상 대미지 이벤트는 한 근원지에서의 방사상 대미지를 모델링한 것으로, 폭발이 명확한 예제가 됩니다. 폭발의 진원지, 공간을 통한 대미지 감쇠를 나타내는 데이터, 영향받은 컴포넌트 목록이 들어있습니다.

FDamageEvent

"아야."

가장 일반적인 대미지 모델로, DamageTypeClass 옵션만 들어있습니다.

내장된 이벤트 유형 중 필요한 것이 없는 경우, FDamageEvent 에서 구조체를 파생시킨 다음 필요한 데이터를 저장하면 됩니다.

블루프린트에서의 대미지

블루프린트에서의 대미지 처리도, 대미지 적용과 반응이 미이 이벤트 유형으로 나뉘어 있다는 점만 빼고는 비슷합니다. ApplyDamage, ApplyPointDamage, ApplyRadialDamage 와 같이 대미지를 입히기 위해 전역에서 접근 가능한 노드가 있습니다. 대미지 이벤트에 대한 반응으로는, 액터 클래스와 레벨 내 액터 인스턴스 양쪽에 대한 유사 "took damage" 이벤트 시리즈가 있습니다.

프로젝트에 커스텀 대미지 이벤트를 정의한 경우, 블루프린트에 사용할 비슷한 함수와 델리게이트 세트를 노출시키는 것이 좋을 것입니다.

즐거운 대미지 작업 되시길! 대미지 관련 요청이나 일화가 있으신 분들께서는 포럼(영문)에, 한글 사용자 분들은 네이버 카페에  왕림해 주시기 바랍니다!

최근 게시글

2018년 언리얼 엔진 기대작

주요 매체들에서는 새해가 시작되면서 2018년 최고의 기대작들을 꼽고 있으며, 이 기대작 목록에는 언리얼 엔진 타이틀이 가득 들어있습니...

2017년 12월 NVIDIA Edge 프로그램 수상자

언리얼 커뮤니티가 다시 한번 나섰습니다. 이번에 NVIDIA GTX 1080Ti를 타게 된 놀라운 프로젝트들을 확인해 보시고, 여러분도...

LA에서 열리는 언리얼 엔진 VFX 마스터클래스

에픽게임즈의 언리얼 엔진 전문가들이 nomon VFX 학원에서 리얼타임 퍼포먼스를 주도하는 기본 개념과 워크플로우에 대한 두 가지 마스...