본문 바로가기

언리얼엔진

28. 세트 컨테이너 / 시퀀스 노드 / 공격 시 충돌 수정

한번의 공격에 여러번 충돌되는 문제 해결하기

BP_Weapon의 이벤트그래프

BP_Weapon에서 OverlappedActors 변수를 하나 추가했다.

충돌 발생 시 해당 변수에 충돌된 Actor가 담겨있는지 먼저 확인을 할 것이다.

만약 변수에 충돌된 Actor가 없다면 Apply Damage가 발생하고, 이 변수에 충돌된 모든 Actor를 담아둘 것이다.

때문에 OverlappedActors 변수의 유형을 Actor로 만들고 세트 컨테이너로 설정을 하였다.

 

※ 세트 컨테이너란?

맵과 비슷하지만 중요한 차이점이 있다. 독립된 키로 데이터 값을 연결하기 보다는 데이터 값 자체를 키로 사용하며,

이때 엘리먼트를 값을 평가하는 오버라이드 가능 함수를 사용합니다.

무엇보다 추가, 검색, 제거가 매우 빠릅니다. 중복 키를 지원하지 않지만, 템플릿 파라미터로 사용할 수는 있습니다.

 

후에 OverlappedActors 변수에 들어간 Actor들은 공격이 끝나면 다시 비워주게 된다.

따라서 DeactivateAttack 함수 마지막에 OverlappedActors 변수를 Clear로 비워주었다.

BP_Weapon의 DeactivateAttack 함수


피격 / 사망처리 애니메이션 출력하기

우리가 Dodge 기능을 구현할 때, BackStep과 Roll 애니메이션을 몽타주로 만든 후, DataAsset을 만들어 관리했었다.

따라서 이번에 Hit과 Die 애니메이션도 같은 방식으로 사용할 것이다.

 

Die와 Hit 애니메이션의 몽타주를 생성

Die와 Hit 애니메이션의 몽타주를 생성해주고, 몽타주의 슬롯을 DefaultGroup.FullBody로 바꿔주는 것을 잊지 말자.

이어서 각각의 몽타주를 넣을 DataAsset 2개를 만들었다.

 

기타 - 데이터에셋 - 데이터 에셋 클래스 선택 : BP_MontageDataAsset을 선택하여

CharacterDamaegdData / CharacterDiedData 두 개의 DatatAsset을 만들었다.

DataAsset 두 개 추가

 

각각 DataAsset에 들어가서 해당하는 몽타주들을 넣어주는데, Hit 몽타주만 PlayRate를 1.25로 수정했다.

그리고 BP_Character의 MontageDataMap 변수에 엘리먼트를 추가하여 아까 추가한 DataAsset 두개를 설정한다.


AnyDamage 이벤트에서 피격 시 몽타주 재생 로직을 구현해줄 것이다.

가로로 노드가 계속 길어질 것을 대비하여 시퀀스 노드를 사용하였다.

 

※ 시퀀스 노드

FlowControl 중에 하나이며, S + 좌클릭으로 바로 생성할 수 있고, 출력 핀에 있는 내용들을 순차적으로 실행한다.

가로로 길게 노드들이 배치되는 것을 막기 위해서 사용한다. Delay 노드와 연계하여 사용할 수도 있다.

시퀀스


먼저 시퀀스의 Then 0번 실행핀으로 실행되고, 피격 시 체력이 깎이는데 LifeNow가 0.0보다 큰지 Branch 노드를 통해 검사해준다. 값이 True라면 Charater의 State를 Damaged로 바꿔주고, False라면 Died로 바꿔준다.

그리고 Died로 몽타주고 재생되고 나면 더이상 피격되면 안되기 때문에 해당 Character의 Capsule 컴포넌트의

Generate Overlap Events를 꺼주면 된다.

시퀀스 Then 0번 실행핀


시퀀스의 0번 실행핀이 끝나면 바로 1번 실행핀으로 넘어갈텐데 여기서 몽타주 재생을 해주면 된다.

이후에 죽는 몽타주가 재생되고 나서 다시 Idle 애니메이션이 나오는 문제가 있는데 이를 해결하는 3가지 방법이 있다.

 

1. 몽타주 재생 후, OnBlendOut에서 IsState : Died 검사를 통해 DestroyActor로 시체를 소멸시킴

2. 몽타주 다음 실행핀에서 Set LifeSpan(설정해둔 값(초) 뒤에 자동으로 소멸) 노드를 사용하여 소멸

3. Die 몽타주 내에 EnableAutoBlendOut을 꺼주면 BlendOut이 일어나지 않고 끝 지점에 몽타주가 멈춤.

 

여기서는 1번의 방법을 사용하였다.

시퀀스 Then 1번 실행핀


Enemy가 무기를 가지고 있는 상태라면 무기도 같이 소멸시켜주어야 하므로 BP_Character의 오버라이드 함수 중에

Destroyed 이벤트 함수를 추가 - ForEachLoop(F + 좌클릭)을 통해서 Weapons 배열 안에 있는 ArrayElement 하나하나를

모두 DestroyActor로 지워주었다.