1. 세 가지 함수의 역할
* FixedUpdate()
- 물리 연산 루프 (Time.fixedDeltaTime 간격) Rigidbody 이동, AddForce, 충돌 계산
* Update()
- 프레임 루프 (모니터 주사율 기준) 입력 처리, 일반 Transform 이동
* LateUpdate()
- 렌더 직전 카메라 추적, 후처리, 위치 보정
2. 실행 순서 요약
FixedUpdate (0~N회) → Update → LateUpdate → Render
Unity는 물리 루프(FixedUpdate) 와 그래픽 루프(Update) 를 분리해서 서로 다른 속도로 독립적으로 실행합니다.
* FixedUpdate() : 일정한 물리 시간 단위로 반복
* Update() : 프레임마다 한 번씩
* LateUpdate() : 렌더 직전 한 번
3. 핵심 개념 : Update와 FixedUpdate의 관계
Update()에서 transform을 변경하면, 그 값은 물리엔진(PhysX)이 아직 모르는 상태입니다.
하지만 FixedUpdate()가 실행되어 물리 연산이 끝나면,PhysX는 모든 Rigidbody의 위치와 회전값을 계산해 Transform에 반영합니다.
Update → 물리 계산 전 상태
FixedUpdate → 물리 계산 수행
Update(다음 프레임) 에서는 이미 물리 결과가 반영된 Transform을 보게 되는 겁니다.
이 차이를 이해해야 물리 오브젝트를 Update()에서 움직였을 때 왜 덜덜거리거나 튀는 현상이 생기는지도 명확히 알 수 있습니다.
4. 올바른 이동 구조
(1) 물리 기반 이동 : FixedUpdate
void FixedUpdate()
{
float dt = Time.fixedDeltaTime;
rb.MovePosition(rb.position + moveDir * moveSpeed * dt);
}
Rigidbody 이동은 항상 FixedUpdate에서.
충돌, 마찰, 중력 등 물리 계산이 정상적으로 작동.
(2) 비물리 이동 : Update
void Update()
{
transform.position += moveDir * moveSpeed * Time.deltaTime;
}
Transform 만 가진 객체는 Update에서 자유롭게 이동 가능.
물리엔진이 관여하지 않기 때문에 덜덜거림이 없습니다.
5. 카메라 떨림이 생기는 이유
카메라의 떨림(jitter)은 플레이어가 언제, 어떤 방식으로 위치를 갱신하느냐에 따라 발생합니다.
플레이어가 Rigidbody를 이용해 물리 기반으로 이동하는 경우 이동은 FixedUpdate() 단계에서 PhysX 물리 엔진에 의해 처리됩니다. 그런데 카메라가 Update()에서 player.position을 읽으면 이 값은 현재 프레임의 실시간 위치가 아니라, 조금 전 FixedUpdate에서 물리 계산으로 Transform에 반영된 위치값입니다.
그 결과 렌더링 시점보다 약간 이전의 위치를 참조하게 되어 화면이 한 박자 늦게 반응하는 듯한 떨림이 발생합니다.
한편, 플레이어가 Transform을 직접 이동시키는 비물리 제어 방식이라도 충돌 감지는 여전히 물리 엔진(PhysX)이 FixedUpdate 단위로 처리합니다. 만약 충돌 후 프로그래머가 위치를 직접 보정했다면 카메라가 그 보정된 위치를 반영하기 전까지 미세한 어긋남이 생길 수 있습니다.
6. 해결 방법 : 카메라는 LateUpdate 에서
void LateUpdate()
{
transform.position = player.position + offset;
}
LateUpdate() 는 렌더링 직전에 호출됩니다.
이 시점에는 모든 물리 계산(FixedUpdate)과 Transform 갱신(Update)이 끝난 상태이므로 카메라는 최종 확정된 플레이어의 위치를 기준으로 부드럽게 따라갈 수 있습니다.
즉, 플레이어가 물리 기반으로 움직이든 Transform을 직접 이동시키되 충돌만 물리로 처리하든, 카메라의 추적 로직은 LateUpdate에서 실행하는 것이 가장 안전한 방법입니다.
7. 마무리
Update() 에서 변경된 위치는 아직 물리엔진이 모르는 값이고, FixedUpdate() 에서 물리 계산이 끝나면 그 결과가 Transform에 반영됩니다.
그리고 Update() 는 그 “물리 연산이 완료된 상태”를 기준으로 실행됩니다.
< 참고 >
Event function execution order :
https://docs.unity3d.com/Manual/execution-order.html
'Unity' 카테고리의 다른 글
| Cinemachine Camera : Dead Zone, Hard Limits, Damping (0) | 2025.07.27 |
|---|---|
| Rigidbody 를 사용하면서, transform 코드가 제대로 동작을 안할 때 (0) | 2025.07.16 |
| Cinemachine 카메라를 붙였더니 카메라가 말을 안 들어요 (0) | 2025.07.16 |
| 물리 공간과 오브젝트 공간에서의 물체 이동 (0) | 2025.07.14 |
| Input Sytem : InputAction 사용법 정리 (0) | 2025.07.14 |