Make Unreal REAL.
article thumbnail
이득우의 언리얼 C++ 게임 개발의 정석

 

언리얼에서 콜리전은 크게 세 가지 방법으로 제작할 수 있다.

  • Static Mesh 에셋
Static Mesh 에셋에 콜리전을 심으면 Static Mesh 컴포넌트에서 비주얼과 충돌을 모두 관리할 수 있어 간편하다.
  • 기본 도형(Primitive) 컴포넌트
구, 박스, 캡슐 등의 기본 도형을 사용해 충돌을 처리한다.
Static Mesh의 모양에 관계 없이 충돌 영역을 설정한다.
보통 Skeletal Mesh를 움직일 때 주로 사용한다.
  • 피직스(Physics) 에셋
캐릭터의 각 관절이 흐느적거리는 래그돌(RagDoll)을 구현할 때 사용한다.
캐릭터의 각 부위에 기본 도형으로 충돌 영역을 설정하고 이를 연결해 구현한다.
피직스 에셋은 Skeletal Mesh에만 사용할 수 있다.

 

충돌체는 반드시 하나의 Collision 채널을 설정해야 한다.

 

언리얼 엔진은 6개의 오브젝트 채널, 2개의 트레이스 채널, 총 8개의 기본 Collision 채널을 제공한다.

 

오브젝트 채널(Object Channel)

Collision 영역에 지정하는 채널

WorldStatic

  • 움직이지 않는 정적인 배경 오브젝트에 사용한다.
    주로 Static Mesh 액터에 있는 Static Mesh 컴포넌트에 사용한다.

WorldDynamic

  • 움직이는 액터에 사용한다.
    블루프린트에 속한 Static Mesh 컴포넌트에 사용한다.

Pawn

  • 플레이어가 조종하는 물체에 주로 사용한다.
    캐릭터의 충돌을 담당하는 캡슐 컴포넌트에 사용된다.

PhysicsBody

  • 물리 시뮬레이션으로 움직이는 컴포넌트에 설정한다.

Vehicle

Destructible

 

트레이스 채널(Trace Channel)

구를 이용한 공격 판정 등 어떤 행동에 설정하는 채널

Visibility

  • 배경 물체가 시각적으로 보이는지 탐지하는데 사용한다.
    폰은 제외되며 마우스로 물체를 선택하는 피킹(Picking) 기능을 구현할 때 사용한다.

Camera

  • 카메라와 물체 간 장애물이 있는지 탐지하는데 사용한다.
    물체가 카메라의 시야를 가릴 때 장애물 앞으로 줌인하는 기능에 사용된다.

 

 

Collision Enabled 옵션은 물리 기능을 어떻게 사용할지 정한다.

 

Query

  • 충돌 영역의 Overlap(겹침)을 감지하며 BeginOverlap 이벤트가 발생한다.
    물체가 충돌하는지 탐지하는 레이캐스트(Raycast)와 스윕(Sweep) 기능도 이에 속한다.
    Generate Overlap Events 옵션을 활성화해야 Overlap 이벤트가 발생한다.

Physics

  • 물리적인 시뮬레이션을 사용할 때 설정한다.

Query and Physics

  • 둘을 모두 사용하지만 부하가 커진다.

 

 

캐릭터의 루트 컴포넌트인 Capsule 컴포넌트에는 Pawn 채널과 Query and Physics 옵션이 기본으로 설정되어 있다.

  • Collision Presets: Pawn은 프리셋 Pawn을 뜻하는 것이고, Object Type: Pawn이 채널을 의미하는 것이다.

 

 

이미지 상 비활성화 되어 있는 Collision Responses 옵션은 현재 채널이 다른 채널과 어떻게 반응할지를 의미한다.

 

Ignore

  • Collision이 있어도 충돌이 일어나지 않는다.

Overlap

  • 물체를 뚫고 지나가지만 이벤트를 발생시킨다.
    BeginOverlap 이벤트가 발생한다.

Block

  • 뚫고 지나갈 수 없다.
    Hit 이벤트가 발생한다.
    양쪽 컴포넌트에 Generate Overlap Events 옵션이 모두 활성화되어 있다면 BeginOverp 이벤트도 발생한다.

 

 

서로 다른 충돌 반응 간에는 아래와 같은 우선순위를 갖는다.

 

 

Project Settings - Engine - Collision에서 새로운 Collision 채널과 프리셋을 만들 수 있다.

  • 32비트로 표현되는 채널 중 언리얼 엔진이 제공하는 8개의 기본 채널과 Gizmo를 제어하기 위해 자체적으로 사용하는 6개의 채널을 제외하면 사용자는 나머지 18개의 채널을 생성할 수 있다.

 

참고로, Static Mesh 컴포넌트의 기본 프리셋은 BlockAll이다.

 

아래에서는 기본 반응이 Block인 ABCharacter 오브젝트 채널과 기본 반응이 Ignore인 Attack 트레이스 채널을 만들었다.

  • Attack 트레이스 채널의 기본 반응은 Ignore이지만 ABCharacter 채널과는 공격 판정을 하기 위해 Block으로 지정했다.

 

 

특히, 오브젝트 채널을 추가했을 때는 가장 먼저 해야 할 일이 있다.

각 Collision 프리셋에서 다른 Collision 채널과 문제가 없도록 조정하는 작업이다.

 

현재 ABCharacter 채널의 기본값이 Block인데 채널에 따라 Block하면 안 되는 경우도 있다.

  • 대표적으로 Trigger, OverlapAll, OverlapAllDynamic, UI 등이 있다.

 

 

SetCollisionProfileName() 함수를 이용해 Collision 프리셋을 지정할 수 있다.

 

 

SweepSingleByChannel(), LineTraceByChannel() 함수 등을 사용하려면 설정할 채널이 몇 번째 채널인지 알아야 한다.

 

프로젝트 폴더의 Config/DefaultEngine.ini 파일의 하단 부분에서 찾을 수 있다.

 

 

공격 판정을 위한 AttackCheck() 함수를 선언한다.

  • BP 연동 없이 C++ 코드에서만 사용할 것이므로 UFUNCTION() 매크로를 지정하지 않아도 된다.

 

 

게임 월드가 물리 법칙이 동작하는 공간이기 때문에 물리 관련 함수는 GetWorld()를 통해 가져온다.

 

GetWorld()->SweepingSingleByChannel() 함수를 이용해 공격을 판정한다.

 

옵션들을 살펴보면 다음과 같다.

  • 액터의 위치에서 전방 200cm까지 쓸면서 추적한다.
  • 기본 회전을 갖는 반지름 50cm의 구를 사용한다.
    박스, 캡슐 등을 사용할 수도 있다.
  • Attack 채널로 설정한다.
  • Trace Tag를 설정하지 않고 복잡하지 않은 추적으로 진행하며 현재 액터는 무시하도록 한다.

 

GetWorld()->SweepingSingleByChannel() 함수는 bool 타입의 성공 여부를 반환하며 FHitResult 구조체를 레퍼런스로 받아 정보를 저장한다.

  • 감지된 액터를 FHitResult.Actor.IsValid()로 검증하는 이유는 이 구조체의 Actor 변수는 참조로 인해 언리얼 런타임이 해당 액터를 GC로 처리하지 못하는 것을 방지하기 위해 약 포인터(TWeakObjectPtr) 방식으로 선언되어 있기 때문이다.
  • 약 포인터 방식은 참조로부터 자유롭게 포인터 정보를 전달해주지만 사용하기 전에 유효한지 우선 확인해야 한다.

 

 

PostInitializeComponents() 함수에서 애니메이션 몽타주의 AttackHitCheck 노티파이에 실행되는 멀티캐스트 델리게이트에 AttackCheck() 공격 판정 함수를 등록한다.

  • AddUObject() 함수를 사용했지만, 굳이 쓰겠다면 함수를 만들지 않고 AddLambda() 함수와 람다 함수로 구현해도 된다.

 

 

공격 판정에 성공했다.

 

'Unreal Engine > 이득우의 언리얼 C++ 게임 개발의 정석' 카테고리의 다른 글

데미지 프레임워크  (0) 2023.03.09
디버그 드로잉  (0) 2023.03.09
콤보 공격 구현  (0) 2023.03.08
애니메이션 노티파이  (0) 2023.03.07
델리게이트(Delegate)  (0) 2023.03.07
profile

Make Unreal REAL.

@diesuki4

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그