요즘 취미 삼아 고도엔진(Godot Engine)을 공부하고 있다.
국내에도 몇 있는 고도엔진 튜토리얼을 살펴보면 알 수 있듯이, 고도에서는 각 노드의 _process()와 _physics_process()를 이용해 주기적으로 처리되어야 하는 로직을 구현할 수 있다.
그런데 이 둘은 어떻게 다른 걸까?
해당 주제와 관련된 고도의 공식 문서에서는, Idle Processing과 Physics Processing에 대해 설명하고 있다.
Idle Processing은 매 프레임 실행된다.
60FPS에서는 1초에 60번, 30FPS에서는 1초에 30번 실행된다는 것을 의미한다.
즉, Idle Processing은 기기 환경이나 최적화에 따라 실행 주기가 가변적이다.
Physics Processing은 매 Physics Frame마다 실행된다.
Physics Frame은 실제 프레임과 무관하게 물리 연산이 일어나는 시기를 의미한다.
Physics Frame의 기본값은 초당 60번이다.
즉 Physics Processing은 안정적인 60FPS의 Idle Processing과 동일한 주기로 일어난다.
Idle Processing은 _process() 메서드,
Physics Processing은 _physics_process() 메서드에 의해 일어난다.
정리해보자.
_process)은 매 프레임 실행되고, 따라서 가변적이다._physics_process)은 프로젝트 내 고정적인 주기로 실행된다.그렇다면 왜 고정적인 주기로 실행되는 Physics Processing이 필요할까?
당연히 물리(Physics)의 동작은 프레임과는 별개로 이루어져야 된다.
물리는 FPS와 무관하게, 일정하게 작동해야 하기 때문이다.
그런데, _process와 _physics_process는 모두 delta를 매개변수로 갖는다.
이 delta는 이전에 해당 함수가 일어난 이후 지난 시간을 의미한다.
예를 들어, 60FPS에서 _process의 delta는 1/60초를 의미할 것이다.
사실 이 delta를 이용해 _process의 동작을 일정하게 만들 수 있다.
프레임률이 달라져 _process의 실행 주기가 바뀐다면, 그만큼 delta의 값도 변하기 때문에 이를 반영할 수 있기 때문이다.
(그래서 일부 블로그 등지에 등장하는, _process를 사용하면 프레임률마다 캐릭터 이동속도가 바뀌니 뭐니 하는 말은 사실 옳은 이야기는 아니다.)
다만, 그럼에도 불구하고 _physics_process를 사용하는 이유는 아래와 같다.
전자는 생각해보면 간단한 이야기다.
초당 60번 일어나야 하는 물리 연산이 있다고 하자. _process를 사용해서 이 연산을 구현하면 낮은 프레임률, 이를테면 30FPS에서는 이 연산이 30번밖에 이뤄지지 않는다.
물론, delta를 이용해 값 자체는 보정할 수 있지만, 연산이 가변적인 간격에 의해 이루어지고, 최소 주기를 보장할 수 없기 때문에 불안정한 결과를 낳을 수 있다.
후자의 Physics Step은 충돌 등 고도 엔진의 물리 작동이 일어나는 단계이다.
이를테면 어떤 물체의 이동을 구현했다고 하자.
그렇다면 이 물체는 이동한 다음에 충돌 이벤트를 발생시키는 것이 바람직할 것이다.
매 루프마다 물체가 충돌을 먼저 체크하고, 그 이후 이동이 일어난 다음, 그 이동에 대한 충돌 판정은 다음 루프에서 일어난다고 생각해보자. 직관성도 떨어지고 의도치 않은 결과를 내놓을 수도 있다.
_physics_process는 매 Physical Step 이전에 호출된다. 반면, _process는 싱글스레드 환경의 경우 Physical Step 이후에 호출된다.
_process와 _physics_process의 사용처는 아래와 같이 결정할 수 있다.
_process에 구현한다._physics_process에 구현한다._process)은 프레임률과 동기화되어 일어나고, 따라서 시각적 요소 처리에 사용한다._physics_process)은 해당 프로젝트의 설정에 의해 고정되어 있으므로 안정적인 물리 처리 등을 위해 사용한다.delta를 갖는다.Idle and Physics Processing - Godot Docs 4.3
Difference between _process() and _physics_process() - 고도엔진 포럼