목표
- Overlap (겹침) 에 이어서, Block (막힘) 충돌 처리를 익힌다.
- DeltaTime의 개념을 익힌다.
Block
UE에서의 충돌반응은 무시 (Ignore), 겹침 (Overlap), 막힘 (Block) 3가지 종류가 있었다. 이번에는 그 중 막힘 (Block)에 대해 알아본다.
우선, 충돌을 테스트할 액터 클래스를 새로 만든다. BP_Box 에서 파생시켜 BP_Hit 를 생성한다.
> [BP_Box] 우클릭 - [자손 블루프린트 클래스 생성] 선택 (이름 : BP_Hit)

콜리전 프리셋
콜리전 컴포넌트를 막힘으로 충돌처리 하고 싶다면 건드려야 할 옵션이 있다.
> 충돌 옵션을 바꾸고자 하는 콜리전 컴포넌트 선택 - [디테일] - [콜리전] - [콜리전 프리셋] - [BlockAll] 선택

콜리전 프리셋의 기본값은 OverlapAllDynamic 이다. 이 옵션 때문에 기본적으로 충돌은 겹침 (Overlap) 으로 처리되고 있었다. 막힘으로 처리하고 싶다면 이를 BlockAll 또는 BlockAllDynamic으로 바꿔주면 된다.
아래 주황색 박스 부분은 콜리전 프리셋에 대한 세부 옵션이다. 각 콜리전 프리셋마다 세부 옵션은 정해져 있지만, Custom 을 선택할 경우 세부 옵션을 원하는 대로 설정할 수도 있다.
이렇게 설정하고 나면 해당 콜리전과 충돌하는 다른 콜리전들은, 그 충돌 옵션이 어떻든 간에 막힘으로 처리된다.
Hit 이벤트
충돌이 성공적으로 처리되고 있다면, 충돌 시에 어떤 처리를 할지도 중요하다. 겹침 (Overlap) 충돌 이벤트에서 보았듯이, 막힘 (Block) 충돌을 처리하는 이벤트도 따로 존재한다. Hit 이벤트이다.
> [BP_Hit] - [내 블루프린트] - [함수] - [오버라이드] - [Hit] 선택

설명에서 알 수 있듯이 Hit 이벤트는 액터 자신이 블로킹 오브젝트가 아니더라도 다른 블로킹 오브젝트와 부딪치면 양쪽 액터 모두에 발생한다.
물리 시뮬레이션
> 콜리전 컴포넌트 - [디테일] - [피직스] - [Simulate Physics]
물리 시뮬레이션을 적용하는 옵션이다. 이 옵션이 켜져있으면 중력 등 물리적 영향을 받는다.

하지만 위 옵션으로 물리적 움직임을 받게 되면 블로킹 오브젝트와 충돌하더라도 Hit 이벤트가 발생하지 않는다. 그래서 아래와 같은 옵션이 따로 있다.
> 콜리전 컴포넌트 - [디테일] - [콜리전] - [Simultation Generates Hit Events] 체크

위 옵션이 켜져있는 콜리전 컴포넌트는 물리 시뮬레이션을 적용받더라도 Hit 이벤트를 다시 제대로 발생시키게 된다.

ActorBeginOverlap 의 막힘 (Block) 버전이다.
- My Comp : 부딪힌 자신의 컴포넌트
- Other : 부딪친 상대 액터
- Other Comp : 부딪친 상대 컴포넌트
- Self Moved : 자신이 움직여서 부딪치면 True, 상대가 이동해와서 부딪치면 False를 반환
Hit 이벤트는 예를 들면, 다음과 같이 사용할 수 있다.

위 스크립트는 (막힘) 충돌 시 자신과 충돌한 상대 컴포넌트의 이름과, 자신이 움직였는지 혹은 상대가 움직여서 충돌했는지 여부를 True, False로 출력한다.
DeltaTime
게임은 본질적으로 애니메이션과 같다. 화면에 연속적인 이미지를 출력한다는 점에서 그렇다. 하지만 애니메이션이든 게임이든 화면 상에 보이는 것은 실제로 연속된 이미지가 아닌, 정지된 사진 또는 이미지들의 모임일 뿐이다. 애니메이션 (동영상) 에서는 이 정지된 사진 하나를 프레임이라고 부른다. 게임에서는 정지된 이미지를 출력하는 한 순간을 프레임이라고도 한다.
즉, 게임은 연속된 프레임의 모임이다. 매 프레임마다 이미지를 렌더링하여 화면 상에 계속 출력한다. (애니메이션과 다른 점이 있다면 유저로 부터 실시간 입력을 받아 개발자가 정해놓은 규칙에 따라 서로 다른 이미지를 보여준다는 것이다.) 그리고, 1초당 지나가는 프레임 수를 fps (frame per second; 분당 프레임 수) 라고 한다. 컴퓨터의 성능에 따라 혹은 게임에따라 fps는 다르게 나타날 수 있다. 문제는 바로 여기서 발생한다.
게임에서는 BeginPlay, Hit 등 특정 상황이 발생했을 때만 발생하는 이벤트도 있지만 매 프레임마다 발생하는 이벤트도 있다. Tick 이벤트이다.

일정한 속도의 이동 (등속도 운동)은 매 프레임마다 현재 위치에 일정한 값을 더하는 것으로 구현할 수 있다. 이것은 Tick 이벤트를 통해 구현할 수 있다. 하지만 fps가 다르면 같은 1초 동안, 서로 다른 수의 프레임이 지나갈 것이다. 그만큼 발생하는 Tick 이벤트의 횟수도 달라질 것이다. 결과적으로 두 물체에 값이 더해지는 횟수가 달라진다. 이것은 같은 시간동안 이동한 거리가 달라지는 것을 의미한다. 두 물체의 속력이 달라지는 것이다 (Tick 이벤트의 정의는 같은데도!)
여기서 DeltaTime 이라는 개념이 등장한다. DeltaTime은 한 프레임에서 다음 프레임으로 넘어가는데 걸리는 시간이다. 예를 들어 현재 fps가 100이라면 DeltaTime은 평균적으로 1 / 100 sec이 된다. fps가 200이라면 DeltaTime은 1 / 200 sec이 될 것이다. 이 DeltaTime을 잘 이용하면 fps가 달라서 생기는 문제를 해결할 수 있다.
예를 들어, Tick 이벤트가 호출될 때마다 일정한 값 A를 더한다고 하자. fps가 n이라면 1초에 Tick 이벤트가 n번 호출되어 1초에 총 A*n 만큼의 값이 더해질 것이다. 여기서 fps가 n이라면 DeltaTime은 1 / n이 되므로 이를 곱해주면 값은 다시 A가 된다. 이것은 fps가 얼마든 간에 1초에 더해지는 값이 A로 일정하게 됨을 보장한다. 즉, Tick 이벤트마다 A가 아닌 A * DeltaTime을 더해주게 되면 fps에 상관없이 일정한 값을 더하는 결과를 얻을 수 있는 것이다. 이것으로 서로 다른 fps에서도 일정한 속력을 보장하는 로직을 짤 수 있다.

액터의 전방 단위벡터에 100.0, DeltaTime을 곱하여 현재 위치에 더한다. 이것으로 현재 위치에서 앞쪽으로, 초당 100만큼 떨어진 곳에 매 순간 위치하게 된다. Sweep 옵션을 켜주면 현재 위치와 다음에 위치할 곳 사이에서 발생할 충돌을 감지해 준다.
'Unreal Engine 4 > Blueprint' 카테고리의 다른 글
| [블루프린트] 데미지 적용 (0) | 2023.06.09 |
|---|---|
| [블루프린트] 충돌 세부 정리 - 콜리전 프리셋 (0) | 2023.06.08 |
| [블루프린트] 충돌 처리 (오버랩) & 컴포넌트 충돌 (0) | 2023.06.06 |
| [블루프린트] 이동 모션 수정 (0) | 2023.06.01 |
| [블루프린트] 블루프린트 함수 라이브러리 & 로직 수정 (0) | 2023.06.01 |