| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- C++
- c#
- 독서
- System Programming
- PS
- Data Structure
- Online Judge
- Unity
- Toy Project
- Network Programming
- BOJ
- multi-thread
- git
- Today
- Total
I'm FanJae.
[20260522] Unity 정리 ( Unity 물리 엔진 기초 - Rigidbody ) 본문
1. Rigidbody
- Rigidbody는 Unity 물리 엔진을 이용해 오브젝트에 물리적인 특성을 부여하는 Component다.
- Rigidbody를 사용하면 오브젝트가 여러 물리 요소의 영항을 받을 수 있다.
- 중력, 충돌, 힘, 속도, 마찰, 감쇠 등등..
- Unity의 기본 3D 물리 엔진은 Nvidia PhysX를 사용하고 있다.
2. Rigidbody의 주요 속성

- Collision Detect은 더 정밀한 옵션을 사용할수록 연산 비용이 증가하기 때문에 상황에 맞게 적당히 선택해서 써야한다.
3. Rigidbody 이동 방식
3-1. Transform.Translate (권장하지 않음)
transform.Translate(Vecotr3.forward * moveSpeed * Time.deltaTime);
- Transform.Translate() 는 Transform의 위치를 직접 변경한다.
① 특징
- 물리 엔진을 거치지 않음
- 충돌 처리가 부자연스러울 수 있다.
- Rigidbody가 있는 오브젝트에서는 사용을 지양해야 한다.
② 이유
- transform.Translate()는 오브젝트의 위치를 즉시 변경하는 방식이다. 프레임 단위 순간이동의 느낌으로 이해해야 한다. 따라서 이동 경로상의 충돌을 연속으로 검사하며 막는 방식이 아니다.
3-2. AddForce
rb.AddForce(moveDir * force);
- AddForce() 는 Rigidbody에 힘을 가하는 방식이다.
① 특징
- 질량, 마찰, 중력 등의 영향을 받는다.
- 점진적인 가속과 감속이 발생한다.
- 점프, 넉백, 폭발, 밀림 등에 적합하다.
- 정확한 캐릭터 이동에는 부자연스러울 수 있다.
② 적당한 사용처
- 물리적으로 밀려야 하는 오브젝트, 가속/감속이 자연스럽게 느껴져야 하는 이동한다.
③ 부적합한 사용처
- 정확한 위치 제어가 필요한 캐릭터 이동, 즉시 멈추거나 즉시 방향 전환해야 하는 이동
- 격자 이동, 일정한 속도로 딱 맞게 움직여야 하는 오브젝트
※ AddForce()는 호출 즉시 위치가 바뀌지 않고, 물리 엔진의 계산 단계에서 힘이 반영된다. 하지만, 이는 ForceMode에 따라 질량의 영향을 받을 수도 있고, 순간적인 힘처럼 적용할 수도 있다.
3-3. linearVelocity
float currentYVelocity = rb.linearVelocity.y;
Vector3 velocity = new Vector3(moveDir.x * moveSpeed, currentYVelocity, moveDir.z * moveSpeed
rb.linearVelocity = velocity;
- linearVelocity는 Rigidbody의 속도를 직접 지정하는 방식이다.
① 특징
- 속도를 직접 제어할 수 있음
- 이동 속도가 명확함
- Y축 속도를 덮어쓰면 중력이나 점프가 깨질 수 있음
- 일반적으로 X, Z축만 수정하고 Y축은 기존 값을 유지함
② 적당한 사용처
- 일정한 속도로 움직이는 캐릭터
- 수평 이동 속도의 제어가 필요한 경우
- 점프 중에도 이동 속도만 바꾸고 싶을 때(X축, Z축에 대한)
- 투사체처럼 속도를 명확히 지정해야 하는 경우
③ 부적합한 사용처
- 관성, 가속, 감속을 자연스럽게 살리고 싶은 이동
- 외부 힘의 영향을 자연스럽게 누적해야 하는 상황
- Y축 속도를 직접 덮어써야 하는 구조
※ linearVelocity는 Rigidbody가 현재 어느 방향으로 얼마나 빠르게 움직이고 있는지를 나태낸다.
※ 값을 대입하면 기존 속도가 덮어써지기 때문에, 점프나 중력에 영향을 받는 Y축 속도는 기존 값을 유지하는 것이 안전하다.
3-4. MovePosition
Vector3 nextPos = rb.position + moveDir * moveSpeed *Time.fixedDeltaTime;
rb.MovePosition(nextPos);
- MovePosition()은 Rigidbody의 다음 위치를 지정하는 방식이다.
① 특징
- 물리 엔진 흐름 안에서 위치를 이동한다.
- Transform 직접 이동보다 안정적이다.
- Rigidbody 기반 이동에 적합하다.
② 적당한 사용처
- Rigidbody 기반 캐릭터 이동
- 키 입력에 따라 일정한 속도로 이동하는 오브젝트
- Transform 직접 이동보다 안정적인 물리 이동이 필요할 때
- Kinematic Rigidbody를 스크립트로 움직일 때
③ 부적합한 사용처
- 힘, 질량, 관성 중심의 자연스러운 물리 이동
- 밀림, 튕김, 폭발 같은 반응을 중심으로 하는 오브젝트
- 매우 빠르게 움직이는 투사체
※ MovePosition()은 Rigidbody를 지정한 위치로 이동시키는 메서드다.
4. Update와 FixedUpdate
4-1. Update
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
moveDir = new Vector3(horizontal,0.0f,vertical);
}
- Update()는 매 프레임 호출된다.
① 주요 사용처
- 키보드 입력
- 마우스 입력
- 화면 갱신 관련 로직
- 입력은 프레임 단위로 확인하는 것이 자연스럽기 때문에 Update() 에서 처리한다.
4-2. FixedUpdate
- FixedUpdate()는 일정한 물리 주기로 호출된다.
① 주요 사용처
- Rigidbody 이동
- AddForce
- MovePosition
- 물리 계산 관련 로직
- Rigidbody처럼 물리 엔진과 관련된 처리는 FixedUpdate()에서 처리하는 것이 일반적이다.
5. GetComponent를 이용한 Rigidbody 가져오기
- GetComponent()는 현재 게임 오브젝트에 붙어있는 컴포넌트를 가져오는 함수다.
- Rigidbody를 매번 찾지 않도록 Start()나 Awake()에서 한 번만 가져와 변수에 저장한다.
① Update()에서 사용 주의
void Update()
{
rb = GetComponent<Rigidbody>();
}
- Update()와 같은 곳에 GetComponent<> 같은 것은 붙이면 안된다.
- 보통 한 번만 가져와서 재사용하는게 나으며, 불필요한 검색이 반복될 뿐만 아니라, 프레임 단위로 컴포넌트 검색에 대한 비용이 발생할 수 있다.
6. 터널링 현상
- 오브젝트가 빠르게 이동하면 이전 위치에서 다음 위치로 순간 이동한 것처럼 처리될 수 있다.
- 이때 물리 엔진이 중간에 있는 Collider를 감지하지 못하고 통과하는 현상이 발생할 수 있다.
- 이것을 터널링(Tunneling)이라고 한다.
① 예시
- 빠른 총알이 벽을 뚫고 지나감
- 빠른 캐릭터가 얇은 벽을 통과함
② 해당 내용 관련
- Collision Detection
- Continuous 충돌 감지
- 이동 속도 조절 (이동속도가 너무 빠르면 뚫고 지나간다)
7. 사용 예시
using UnityEngine;
public class RigidBasic : MonoBehaviour
{
private Rigidbody rb;
private Vector3 moveDir;
[SerializeField]
private float moveSpeed = 20.0f;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
// 각 이동 처리 확인 뒤, 대각선 이동 보간
moveDir = new Vector3(horizontal, 0.0f, vertical).normalized;
}
private void FixedUpdate()
{
Vector3 nextPos = rb.position + moveDir * moveSpeed * Time.fixedDeltaTime;
rb.MovePosition(nextPos);
}
// 현재 위치에 (방향 *속도*물리 프레임에 걸리는 시간). 즉, 물리 프레임 동안 이동할 거리
// 만큼 Rigidbody 이동.
}
8. 정리
※ Rigidbody는 오브젝트를 Unity 물리 엔진의 계산 흐름 안에서 동작하게 만드는 Component다.
※ 따라서 Rigidbody가 붙은 오브젝트는 Transform을 통해 직접 조작하기보다 상황에 맞게, AddForce, linearVelocity, MovePosition과 같은 Rigidbody 기반 방식을 사용하는 것이 좋다.
※ 이러한 Rigidbody 관련 물리 이동은 FixedUpdate()에서 처리하는 식으로 분리한다. 즉, Rigidbody를 사용할 때는 직접 위치를 바꾼다가 아닌 물리 엔진을 통해 움직이는 것이다.
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260526] Unity 정리 ( Prefab ) (0) | 2026.05.26 |
|---|---|
| [20260522] Unity 정리 ( Collider 충돌 처리 기초 - Collision, Trigger ) (0) | 2026.05.22 |
| [20260521] Unity 정리 ( Unity 회전 처리 기초 - Euler, Quaternion, LookAt, RotateAround ) (0) | 2026.05.22 |
| [20260521] Unity 정리 ( Transform 이동 처리 기초 - Translate, Input, deltaTime ) (0) | 2026.05.21 |
| [20260520] Unity ( Unity의 LifeCycle ) (0) | 2026.05.20 |