[UE4] 발사체를 날린 후, 방향과 도착지점을 예측해 보았다

물리가 적용된 물체에 AddImpulse로 힘을 가하여 물체를 날려보낼 경우, 그 방향과 도착지점을 계산하여 예측해 보았다.  이전에 글에서 발사체를 궤적에 따라 날려보내는 방식을 소개한 적이 있는데, 이 글에서는 매 Tick에서 얻을 수 있는 물체의 속도로 부터 최종 위치를 예측해 보는 방식으로 테스트하였다. 
제한 사항으로는 물체가 날아가는 동안 Linear Damping을 0으로 하였고, 중력가속도는 [latexpage] $ 9800 cm/s^2 $ 으로 세팅하여, 속도에 영향을 줄 수 있는 변수가 최초 속도와 중력만 작용하도록 설정하였고, 물리 서브스테핑 설정을 통해 안정적인 Tick에서 계산이 되도록 환경을 구성하였다.

이제 발사체에 AddImpulse로 힘을 가한 후,  매 Tick마다 월드 스페이스에서의 속도를 얻어서 그 수치를 찍어보자.  속도와 위치를 얻는 API는 다음과 같다.

  • GetUnrealWorldVelocity_AssumesLocked() : 현재 물체의 속도
  • GetUnrealWorldTransform_AssumesLocked() : 현재 물체의 위치 Transform

노란색으로 표시된 속도를 보니, X와 Y의 속도는 일정하게 유지되고, Z의 속도만 매 Tick마다 변하고 있다.  이는 중력 가속도가 적용되기 때문이며 그로 인해 Z의 속도는 점점 증가한다.  붉은 색으로 표시된 것은 이전의 속도가 적용된 현재의 위치이므로 이 위치를 기준으로 계산해 보자.  

첫 줄의 위치(1329.82312, 242.725967, 65.960365)에서 다음 위치를 구하기 위해서는 거리 = 속도 $ * $ 시간 이라는 공식을 이용하면 간단히 구할 수 있다.

  • 다음 X 위치
    • 1329.82312 + (2543.168945 x DeltaTime(= 0.008334)) = 1351.01789
  • 다음 Y 위치
    • 242.725967 + ( -1.713772 x DeltaTime(= 0.008334)) = 242.7116844
  • 다음 Z 위치
    • 65.960365 + (2700.105469 x DeltaTime(= 0.008334)) = 88.46304398

계산된 위치를 붉은 색으로 표시된 위치와 비교 해보면 거의 같다는 것을 알 수 있다 (0.001 정도의 오차).

그럼 다음 Tick에서 물체의 속도를 알 수 있다면, 그 속도로 부터 다음 위치도 알 수 있는 것이기 때문에, Tick의 속도를 한번 계산해보자.  다행스럽게도 X, Y의 속도는 일정하다.  그럼 Z 속도만 미리 계산하면 될 것 같다.

Z 속도는 매 Tick마다 중력 가속도의 영향을 받는다.  그러므로, 현재 속도 $ Z – ( 9800 cm/s^2 * DeltaTime(= 0.008334)) $을 통해 다음 Tick에서의 Z 속도를 구할 수 있다.  그리고 그 얻은 Z 속도를 이용하여 다음 Z 속도도 연속하여 계산 가능하다.  

최종 Z 속도 값으로 -2772.498731 이라는 값을 얻었다.  그럼 기존에 남겼던 로그와 비교해보자.  

0.07정도의 오차가 있지만 꽤 정확한 수치라고 볼 수 있다.  사실 여기에 큰 맹점이 하나 있는데, DeltaTime이 항상 일정하다라는 가정이다.  SubStepping을 이용하면 프레임 드랍에서도 일정한 물리 업데이트를 받을 수 있지만, 이 DeltaTime은 시시각각 변할 수 있다.  그래서 발사체가 날아가는 동안 계속 예측을 시도하여 최종지점을 업데이트 시켜주는 방식이 필요할 것 같다.  그럼 최초 예측한 것보다 날아가는 동안 더 정확한 위치 및 궤도를 얻을 수 있다. 

이제 예측된 X, Y, Z의 속도를 가지고 위치를 계산해보자.

처음에 로그로 남겼던 위치와 거의 비슷한 수치를 얻을 수 있다.  

샘플로 구현하여 DrawDebugPoint로 예측한 지점을 빨간색으로 표시해보았다.   

공이 미리 예측된 궤적을 따라 어느정도 정확하게 잘 날아가는 것으로 보인다.  이는 안정적인 프레임레이트가 나오기 때문이기도 하고, 매 Tick마다 새로운 DeltaTime으로 궤적을 갱신해주기 때문이기도 하다. 


Leave a Reply

Your email address will not be published. Required fields are marked *