[이득우 언리얼 C++] 9. 충돌 설정과 대미지 전달

    💻 Code : https://github.com/tedison7/ArenaBattle

    콜리전 설정

    언리얼 엔진의 물리 엔진을 활용하려면 콜리전(Collision)이라는 충돌 영역에 대해서 학습해야한다. 크게 세가지 방법으로 제작할 수 있다.

    • 스태틱메시 애셋 : 스태틱메시 애셋에 콜리전 영역을 심는 방법
    • 기본 도형 컴포넌트 : 구체, 박스, 캡슐의 기본 도형을 사용해 충돌 영역을 지정하는 방법
    • 피직스 애셋 : 캐릭터의 각 부위에 충돌영역을 설정하는 방법, 래그돌 효과를 구현할 때 사용

    물리 설정은 크게 세 가지로 구분된다.

    1. 콜리전 채널과 기본 반응
    2. 콜리전 채널의 용도
    3. 다른 콜리전 채널과의 반응

    충돌체는 반드시 하나의 콜리전 채널을 설정해야한다. 엔진에서는 기본적으로 8개의 콜리전 채널을 제공한다.

    • WorldStatic : 움직이지 않는 정적인 배경 액터에 사용하는 채널
    • WorldDynamic : 움직이는 액터에 사용하는 콜리전 채널
    • Pawn : 플레이어가 조종하는 물체에 주로 사용, 캐릭터의 충돌을 담당하는 캡슐 컴포넌트에 설정
    • Visibility : 배경 물체가 시각적으로 보이는지 탐지하는데 사용. 피킹(Picking) 기능 구현시 사용
    • Camera : 카메라 설정을 위해 카메라와 목표물 간에 장애물이 있는지 탐지하는데 사용
    • PhysicsBody : 물리 시뮬레이션으로 움직이는 컴포넌트에 설정
    • Vehicle : 탈 것에 사용
    • Destructible : 부서질수 있는 액터에 사용

    콜리전 프리셋 항목중 Collision Enabled 항목이 있다. 해당 컴포넌트에서 물리 기능을 어떻게 사용할지 지정하는 항목이다. 설정 값은 다음과 같다.

    • NoCollision : 물리적으로 아무일도 일어나지 않는다.
    • Query : 두 물체의 충돌 영역이 서로 겹치는지 테스트하는 설정
    • Physics : 물리적인 시뮬레이션을 사용할 때 설정

    그리고 콜리전 프리셋의 다음 항목은 상대 컴포넌트의 콜리전 채널과 어떻게 반응할지 지정하는 항목이 있다.

    • 무시(Ignore) : 콜리전이 있어도 아무 충돌이 일어나지 않는다.
    • 겹침(Overlap) : 물체가 뚫고 지나갈 수 있지만 이벤트가 발생한다.
    • 블록(Block) : 물체가 뚫고 지나가지 못하도록 막는다.

    이제 캐릭터에 직접 Pawn이 아닌 새로운 채널을 만들어 지정해보자. 콜리전 채널은 다시 오브젝트 채널과 트레이스 채널로 나뉜다.

    • 오브젝트 채널 : 콜리전 영역에 지정하는 콜리전 채널 (Visibility, Camera를 제외한 나머지)
    • 트레이스 채널 : 어떤 행동에 설정하는 콜리전 채널 (Visibility, Camera)

    오브젝트 채널에 ABCharacter라는 콜리전 채널을 추가하였다. 기본반응은 블록으로 설정하였다.

    프로파일에도 ABCharacter라는 새 프로파일을 추가하였다. 콜리전 켜짐 항목은 CollisionEnabled로 오브젝트 유형을 ABCharacter로 설정하였다.

    기존 프리셋 항목들에게서 추가한 ABCharacter 프리셋에 대한 세팅을 다음과 같이 하였다.

    • OverlapAll : 겹침
    • OverlapAllDynamic : 겹침
    • IgnoreOnlyPawn : 무시
    • OverlapOnlyPawn : 겹침
    • Spectator : 무시
    • CharacterMesh : 무시
    • RagDoll : 무시
    • Trigger : 겹침
    • UI : 겹침

    그리고 캡슐 컴포넌트가 해당 프리셋을 사용하도록 코드를 작성해보자

    트레이스 채널의 활용

    Attack 이름의 트레이스 채널을 추가하고 기본 반응을 무시로 설정한다. 이어서 Preset설정에서 ABCharacter의 프리셋을 열어 Attack 트레이스 채널과의 설정을 블록으로 지정한다.

    이제 SweepSigleByChannel 함수를 사용해 물리적 충돌 여부를 판단해보도록 하자. 해당 함수의 인자요소들은 다음과 같다.

    • HitResult : 물리적 충돌이 탐지된 경우 관련 정보를 담는 구조체
    • Start : 탐색을 시작할 위치
    • End : 탐색을 끝낼 위치
    • Rot : 탐색에 사용될 도형의 회전값
    • TraceChannel : 충돌 감지에 사용할 트레이스 채널 정보
    • CollisionShape : 탐색에 사용할 기본 도형 정보, 구체, 캡슐, 박스를 사용
    • Params : 탐색 방법에 대한 설정 값을 모아둔 구조체
    • ResponseParams : 탐색 반응을 설정하기 위한 구조체

    TaceChannel은 DefaultEngine.ini 파일에서 확인할 수 있다.

    //----------------------------------------------------
    //DefaultEngine.ini
    ...
    [/Script/Engine.CollisionProfile]
    +DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=False,bStaticObject=False,Name="ABCharacter")
    +DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="Attack")
    ...

    Attack 채널이 ECC_GameTraceChannel2 로 할당되어 있음을 확인할 수 있다. 해당 채널로 공격 판정을 해보자

    컴파일하고 배치한 캐릭터에서 공격을 시도하여 공격판정이 되는지 로그로 확인해보자.

    디버그 드로잉

    엔진의 디버그 드로잉 기능을 사용하여 화면에서 공격 판정을 하는 영역을 그려보자 DrawDebugHelpers.h 파일에 있는 DrawDebugCapsule 함수를 사용하여 표현해본다.

    컴파일을하고 플레이해보면 공격시 공격부위와 판정에 따른 색상이 결정되어 보여진다.

    대미지 프레임워크

    공격 판정을 구현하였고 이제 감지된 액터에 대미지를 전달하는 기능을 만들어보자. 액터클래스 AActor는 TakeDamage라는 함수가 구현돼있다. TakeDamage 함수는 총 4개의 인자를 가지고 있다.

    • DamageAmount : 전달할 대미지 수치
    • DamageEvent : 대미지 종류
    • EventInstigator : 공격 명령을 내린 가해자
    • DamageCause : 대미지 전달을 위해 사용한 도구

    TakeDamage 함수를 오버라이드 하여 구현해보자.

    컴파일후 테스트 해보면 데미지 로그가 출력됨을 확인할 수 있다.

    모든 액터의 설정에는 Can be Damaged 속성이 있고, 이 속성의 체크를 해제하면 캐릭터에 전달된 대미지 결과값이 0이되는 무적상태가 된다.

    이제 대미지를 받으면 캐릭터가 사망하는 애니메이션이 연출되도록 설정해보자 코드에 IsDead 속성을 추가하고 애니메이션 블루프리트로 이동하여 애님 그래프를 수정하였다.

    이제 컴파일후 플레이를 눌러보면 공격받은 액터는 대미지를 받으면 죽는 애니메이션을 재생하는것을 확인할 수 있다.

    요약

    • SweepSingleByChannel 함수를 이용한 충돌 판정
    • DrawDebugCapsule 함수를 이용한 판정 범위 디버그 드로잉
    • TakeDamage 함수로 대미지 처리
    • 사망 애니메이션 연출
    반응형

    댓글

    Designed by JB FACTORY