[UE4] Parkour 기능 -1 (파쿠르가 가능한지 검증, Trace Channels)
🏃♂️ Parkour
플레이어가 자유롭게 높은 담벽을 넘고, 슬라이드하고, 벽을 짚고 기어올라가는 등의 파쿠르 동작을 구현해보았다.
파쿠르 동작을 구현하는데 가장 중요한 요소는 파쿠르가 가능한 상태인지를 검증하는 "검증 절차"를 거쳐야 한다는 점이다.
1. 파쿠르 검증 절차를 위해 LineTrace를 수행할 Arrow 생성
가장먼저, 파쿠르가 가능한 상태인지를 검증하기 위해, 플레이어에 Arrow들을 생성해주었다.
- Ceil : 플레이어의 머리 위를 검사
- Center : 플레이어의 중심 앞을 검사
- Left, Right : 플레이어의 왼쪽 오른쪽을 검사
- Floor : 플레이어의 발 앞을 검사
- Land : 땅의 위치를 검사
만들어진 Arrow에 "Arrows"라는 이름의 Tag를 생성한 뒤, 태그를 불러와 Arrow Group 변수에 저장해두었다.
이후에 화살표 방향으로 Line Trace를 진행할텐데, 이때 각 화살표마다 충돌한 결과를 저장할 Hit Results 변수(변수 유형: Hit Result)를 생성하고, 미리 화살표의 개수만큼 빈 공간의 배열을 만들어놓았다.
각 화살표의 종류는 열거형(Enum)으로도 전부 생성해두었다. 이때 열거형과 캐릭터의 컴포넌트에 추가한 Arrow 순서를 동일하게 맞추어 Hit Results 배열에 인덱스가 열거형 인덱스와 동일하여 Integer 값만으로도 배열을 사용할 수 있게 구성하였다.
2. 파쿠르 가능한 액터가 있는지 검사하기 (Center Arrow 검사, Line Trace)
파쿠르의 검증절차 중 첫번째로 Center Arrow에 추적된 물체가 있는지 검사한다.
Line Trace를 통해 Center Arrow에 충돌된 물체의 정보를 저장할 변수들을 생성하고 각각 초기화해주었다.
- Hit Obstacle : 파쿠르 가능한 장애물 중 Hit 된 액터
- Hit Obstacle Extent : 파쿠르 하려는 물체의 두께
- Hit Obstacle Hit Point : Hit 된 지점
- Hit Obstacle Hit Distance : 플레이어와 Hit 된 액터 간 충돌거리(간격)
- Hit Obstacle Front Yaw : 플레이어의 정면으로부터 Hit 된 액터가 있는 곳까지의 틀어진 Yaw 각도
모든 변수 초기화가 끝나면 곧이어 Line Trace 충돌을 수행한다.
Arrow로 Center Arrow를 받아오고, Get World Location 위치를 받아 시작위치로 설정하면 World 좌표값으로 충돌을 검사할 수 있다.
캐릭터의 Forward 방향으로 Trace Distance(600.0f) 길이만큼의 Trace 범위를 지정하고, 충돌되었다면 플레이어의 Arrow와 같은 색상으로 Trace Color를 변경한 뒤, 충돌된 Hit Result를 Hit Results 배열의 Center 인덱스에 추가해주었다.
Line Trace는 Channel을 이용한 함수로 사용하였는데, Parkour가 가능한 벽과 불가능한 벽을 나누어 가능한 벽만 블록 콜리전을 수행하기 위해 프로젝트 세팅에서 Trace Channels를 새로 생성해주었다.
💡 파쿠르 전용 Trace Channels 만들고 새 프로파일 생성하기
Parkour 라는 이름으로 Trace Channels을 생성하고 기본 반응을 무시(Ignore)로 설정한 뒤, Parkour_Profile 이라는 이름으로 새 프로파일을 만든 뒤, 해당 프로파일만 Parkour를 블록 충돌 하도록 설정하였다.
따라서 파쿠르가 가능한 액터의 콜리전 프리셋만 Parkour_Profile로 설정하면, 일반 벽은 파크루 충돌에서 제외되고, 해당 콜리전 프리셋이 적용된 액터에서만 충돌 검사를 수행하게 된다.
![]() |
![]() |
파쿠르가 가능한 장애물 | 파쿠르가 불가능한 벽 |
Line Trace를 통해 반환된 Hit Result가 존재한다면, 해당 Hit Obstacle (파쿠르 가능한 액터)의 정보를 각각의 변수에 저장해주었다.
플레이어의 Forward 방향으로부터 충돌된 액터까지의 Yaw 각도는 Make Rot from X 함수를 통해 구하였는데, 이때 액터의 Normal 벡터와 플레이어의 Forward 방향벡터는 방향이 반대이기 때문에, 액터의 Normal 벡터에 -1를 곱해서 방향을 뒤집어주었다.
충돌된 액터의 두께를 저장하는 Extent값을 구하기 위해선 액터의 충돌정보가 있는 Static Component에 존재하는 Get Local Bounds 함수를 이용하였다.
Get Local Bounds 함수는 충돌체를 Box로 인식한 뒤 크기를 반환해주는 함수로 앞 왼쪽 하단지점이 Min, 뒤 오른쪽 상단 지점이 Max 위치로 반환한다.
이후 Min 위치와 Max 위치를 뺀 값에 절댓값을 취해서 액터의 앞뒤 두께를 Extent 함수에 초기화하였다.
3. 파쿠르를 수행할 수 있는지 판단하기
공통적으로 저장될 충돌된 액터의 정보 설정이 끝났다면, 이 정보들을 가지고 파쿠르를 수행할 수 있는지 판단하고, 각각의 Arrow 특성에 따라 또다시 판단과정을 거치게 된다.
가장 먼저 검사했던 Center Arrow의 Line Trace 결과에서 Hit Obstacle이 존재한다면 나머지 Arrow들도 모두 Line Trace검사하였다.
파쿠르 기능은 마우스 오른쪽 버튼을 통해 수행할 수 있도록 구현했는데, 해당 입력 액션이 들어오면 DoParkour 함수가 실행되면서 Parkour가 가능한 상태인지 검사하게 된다.
첫번째로, 파쿠르 상태 열거형에서 Type이 Max라면 현재 파쿠르가 아닌 상태이므로 파쿠르 가능한 상태이고,
두번째는 플레이어가 공격이나 데미지를 받는중이 아닌 Idle 상태여야 하고,
세번째로는 파쿠르 장애물과의 거리나 각도가 적정한지를 검사한다.
해당 세 조건이 모두 True인 경우가 파쿠르가 가능한 경우이다.
세번째 조건인 파쿠르 가능 각도와 거리를 판별하기 위해 Check Do Parkour 함수를 작성하였다.
Check Do Parkour 함수의 조건은 총 6가지로, 3가지는 Center, Left, Right들의 Arrow가 파쿠르 장애물과 Hit 되어있는지 이다. 2가지는 플레이어가 파쿠르 장애물의 모서리에 위치하고 있지는 않은지를 검사하는 조건이다.
마지막 1가지는 앞 5개의 조건이 모두 만족했을 때, 장애물과 플레이어가 과도하게 틀어져있다면 파쿠르가 불가능하다는 조건이다.
모서리를 검사하지 않는다면 플레이어가 장애물의 모서리를 기어올라가는 등의 어색한 동작이 나올 수 있으므로 예외시켜주었다.
플레이어가 Center, Left, Right의 Arrow들로 Line을 쐈을 때 장애물의 평면앞에 서있다면 세 개의 Line이 전부 일치하게 나올것이다. 반면, 장애물의 모서리에 위치한다면 세 개의 Line이 다르게 나올것이다.
이런 개념을 이용해서 세 개의 Normal 벡터가 일치해야지만 모서리앞에 위치한 경우가 아니므로 ==를 이용하여 세가지 다 비교하였다.
이때 Impact Normal은 평면 전체의 Normal 벡터를 반환하므로, 세부적인 라인마다 출력되는 일반 Normal 벡터를 이용해야 한다.
다섯 조건을 모두 만족하면 그 다음으로 파쿠르 장애물과 플레이어가 너무 틀어져있진 않은지 검사하는 블루프린트를 작성하였다.
플레이어가 장애물을 바라보는 각도를 Look At 변수에 저장하고, 장애물의 Impact Normal 벡터와 Look At 값에 각각 절댓값(ABS)으로 변환한 뒤 빼면 두 각의 차이가 나온다. 이 각의 절댓값이 Available Front Angle(60도) 보다 작은 경우에만 파크루가 가능한 True 결과를 함수의 반환값으로 주었다.
이렇게 모든 검증 과정이 끝나면 최종적으로 플레이어가 파쿠르를 수행할 장애물앞에 있고, 파쿠르가 가능한 상태인지를 판단할 수 있게 된다.
🚩 모서리에 위치해서 파쿠르가 불가능한 상태
🚩 정면에 위치해서 파쿠르가 가능한 상태
🚩 장애물의 너무 측면에 위치해서 파쿠르가 불가능한 상태