🎮Unreal4/Blueprint

[UE4] 게임 속도 조절, 경직기능, 모빌리티, 딜레이/타이머

공대 컴린이 2023. 2. 1. 23:26
728x90

철권 게임을 보면 플레이어 공격 시에 잠깐 잠깐씩 애니메이션이 멈추는듯한 "경직 부분"이 있다.

이는 플레이어의 타격감을 높이기 위한 기능으로 Hit Stop 기능을 구현해보았다.

🎢 게임 속도 조절

경직 기능을 구현하려고 게임 전체의 속도를 느리게 하는것은 절대 안된다. 게임 타임이나 게임 요소들도 전부 느려지기 때문에 게임 전체시간을 늦추는 것은 지양해야한다. 즉, 경직을 구현하려면 게임 전체 시간이 아닌 액터 자체의 시간을 늦춰야한다.

Set Global Time Dilation

 

Set Global Time Dilation은 게임 전체의 시간을 늦추는 함수이다. 이는 예제로만 사용해보고 실제 게임 구현에는 사용하지 않는다.

Set Custom Tile Dilation

Set Custom Time Dilation 함수를 사용하면 원하는 액터의 시간만 느리게 할 수 있다. 타깃에 늦추고자 하는 액터를 연결하고 Dilation이 1.0일때 정상 속도이기 때문에 0.1~0.9 사이의 지연값을 주면 해당 액터만 느리게 움직이도록 구현할 수 있다.

 

경직 기능을 제대로 구현하기 위해선 순간적으로 움직이는 모든 객체들을 동시에 느리게 만드는 방법이 있다. 

이때 움직이고 있는 객체를 판별하기 위해 모빌리티를 사용한다.

모빌리티 (Mobility)

스태틱: 게임상에서 움직일 수 없어 조명정보나 그림자 등 미리 계산하여 렌더링하는 객체에 사용한다.

무버블: 전부 실시간으로 계산해서 게임상에서의 이동이 가능하다. 따라서 렌더링이 가장 느리다.

스테이셔너리: 그림자같은걸 실시간으로 다시 계산해서 변경은 가능하다. 예를 들어 태양이 움직이면 태양에 따라 달라지는 그림자들을 다시 계산해주는 상황에서 사용하곤 한다.

🏃‍♂️ 경직동작 구현

나는 경직동작에 필요한 경직 시간을 Data Table을 작성하여 전달받았다.

 

- 경직 시간은 float 형이기 때문에 근사값으로 float 값을 비교하는 Nearly Equal(float) 함수를 사용하여 Hit Stop 데이터에 설정값이 0인지 판별한다.

 

- 0이 아니라면 World에서 모든 Actor를 찾아 차례로 for문을 실행한다.

 

- Actor를 차례로 검사하면서 모빌리티를 검사하기 위해 모빌리티가 위치하고 있는 Mesh Component를 가져오고, Mesh Component안에 있는 Mobility 값이 움직이는 Movable인지 검사한다.

 

- Mesh Component가 존재하고, 모빌리티가 Movable이 맞다면 해당 액터를 경직 동작을 수행할 Delation Actors 변수에 추가해준 뒤, Set Custom Time Dilation 함수를 통해 1000분의 1초로 액터들의 시간을 지연시킨다.

 

- 모든 액터의 검사가 끝나 for문이 마무리되면 Set Timer by Function Name 함수를 통해 설정한 경직 시간(Hit Data Hit Stop)이 지난 뒤 설정된 Function Name 함수가 호출된다.

 

- Set Timer함수를 호출하고 난 뒤, Timer는 스레드이기 때문에 기다리지 않고 바로 Exit 함수로 넘어간다. Exit 함수는 해당 이벤트의 출력으로 탈출하게 된다.

 

- RestoreTimeDilation 함수는 경직 시간을 설정했던 모든 액터들의 지연시간을 다시 정상화(1.0으로 설정)하는 함수이다. for문을 돌리면서 모든 액터를 초기화한 뒤, 배열을 Clear 함수로 비워주었다.

딜레이와 타이머의 차이

딜레이는 해당 노드에 도착하여 딜레이함수가 실행된 후, 노드에 일정 시간동안 흐름이 멈춰있다가 설정된 딜레이 시간이 모두 지나고 나서야 다음 노드로 흐름이 움직인다.

그러나 타이머는 일정 시간을 설정해두고 바로 다음 노드로 넘어간 뒤, Set Timer 함수에서 알아서 일정 시간 뒤 지정된 동작을 수행한다. 이는 곧 스레드의 기능이다. 타이머는 별도의 스레드 구역을 만들어서 수행한다.

728x90