Quick Comparison
| 원하는 움직임 | Rigidbody 상태와 API | 호출 위치 | 바로 확인할 점 |
|---|---|---|---|
| 충돌체를 밀며 정해진 속도로 조작 | Kinematic + MovePosition | FixedUpdate | Interpolation은 화면 흔들림을 줄이지만 Interpolate는 한 물리 단계만큼 보이는 위치가 늦습니다. |
| 중력·반동·질량에 반응 | Dynamic + AddForce 또는 linearVelocity | FixedUpdate | AddForce의 ForceMode와 Mass, Linear Damping이 결과를 바꿉니다. |
| 컷신·리셋 위치로 즉시 옮김 | Rigidbody.position 또는 상태에 맞는 Teleport 처리 | 물리 단계 경계에서 | 연속 충돌 이동이 아니며, 직후 물리 query가 필요하면 동기화 시점을 확인합니다. |
MovePosition은 Unity 6의 3D API에서 kinematic Rigidbody를 목표 위치로 이동시키는 용도입니다. 동적 물체를 힘처럼 움직이게 하려면 AddForce나 linearVelocity를 선택합니다. 입력은 Update에서 읽고, Rigidbody 변경은 물리 단계 직전인 FixedUpdate에서 적용합니다.
[SerializeField] private float moveSpeed = 5f;
private Rigidbody _body;
private Vector3 _moveDirection;
private void Awake() => _body = GetComponent<Rigidbody>();
private void Update()
{
_moveDirection = new Vector3(
Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")
).normalized;
}
private void FixedUpdate()
{
Vector3 step = _moveDirection * moveSpeed * Time.fixedDeltaTime;
_body.MovePosition(_body.position + step);
}이동 방식과 Inspector
Kinematic 제어 이동
Is Kinematic이 켜진 Rigidbody는 힘, 충돌, Joint에 의해 자신의 움직임이 바뀌지 않습니다. 플레이어가 정한 경로를 따라가되 다른 dynamic Rigidbody에는 충돌 영향을 주는 플랫폼, 문, 단순한 물리 캐릭터에 맞습니다. MovePosition을 연속 호출하면 Interpolation 설정을 따르는 화면 전환을 만들 수 있습니다.
Interpolate는 앞선 두 물리 상태를 사용하므로 화면상 위치가 한 물리 단계 늦습니다. Extrapolate는 다음 위치를 예측하므로 빠르게 방향을 바꾸거나 충돌한 직후에는 앞서 보였다가 보정될 수 있습니다. 실제로 화면 흔들림이 보일 때만 켜고, 카메라가 따라가는 주 대상부터 확인합니다.
Dynamic 힘 기반 이동
Is Kinematic이 꺼진 Rigidbody는 중력과 충돌 해법의 영향을 받습니다. 점프, 폭발, 밀림처럼 물리 반응이 목적이면 AddForce를 씁니다. 같은 수치라도 ForceMode.Force는 여러 물리 단계에 걸친 힘, Acceleration은 질량을 무시한 가속도, Impulse는 순간 운동량 변화, VelocityChange는 질량을 무시한 순간 속도 변화입니다.
private void FixedUpdate()
{
if (_jumpRequested)
{
_body.AddForce(Vector3.up * jumpImpulse, ForceMode.Impulse);
_jumpRequested = false;
}
}Mass는 Force와 Impulse 결과에 영향을 주고, Linear Damping은 속도가 줄어드는 정도를 정합니다. 캐릭터처럼 매 단계 목표 속도를 직접 만들 경우에는 linearVelocity를 의도적으로 설정할 수 있지만, 중력 축까지 덮어쓰지 않도록 필요한 축만 바꿉니다.
Vector3 velocity = _body.linearVelocity;
velocity.x = _moveDirection.x * moveSpeed;
velocity.z = _moveDirection.z * moveSpeed;
_body.linearVelocity = velocity;Transform을 함께 바꿀 때
Rigidbody가 물리와 보간을 관리하는 동안 transform.position을 계속 바꾸면 Rigidbody의 물리 상태와 Transform 변경 시점이 엇갈릴 수 있습니다. 특히 Interpolation 또는 Extrapolate를 켠 물체는 physics 시스템이 Transform을 제어합니다. 꼭 직접 Transform을 바꾼 뒤 같은 물리 단계 전에 raycast 같은 query를 해야 한다면 Physics.SyncTransforms()의 비용과 필요성을 별도로 검토합니다.
실패를 찾는 순서
| 증상 | 먼저 확인할 항목 | 흔한 원인 |
|---|---|---|
| 제어 이동이 힘·중력에 밀림 | Is Kinematic, Use Gravity | kinematic 이동과 dynamic 물리를 한 역할에 섞었습니다. |
| 이동이 화면에서 덜컥거림 | Interpolation, 카메라 추적 시점 | 물리 단계와 렌더 프레임의 간격 차이가 보입니다. |
| 빠른 물체가 얇은 벽을 통과 | Collision Detection, 속도, Collider 두께 | 이동 API만 바꾸고 continuous collision 조건을 확인하지 않았습니다. |
| 점프 높이나 가속이 질량에 따라 달라짐 | ForceMode, Mass | 질량을 반영하는 모드를 질량 독립 동작에 사용했습니다. |
MovePosition을 dynamic Rigidbody의 힘 기반 이동 만능 API로 취급하지 마세요. 이 카드는 kinematic 제어 이동을 기준으로 합니다. 충돌 반응이 이동 결과를 바꿔야 하면 dynamic Rigidbody와 힘·속도 설계를 선택하고, 정해진 경로를 따라가야 하면 kinematic 이동과 collision detection 설정을 함께 검증합니다.
참고 링크
3 sources