게임에서 물리엔진을 빼고는 설명할 수 없을 정도로 중요한 개념입니다.
유니티에서는 Rigidbody를 통해 게임 오브젝트에 물리엔진을 적용합니다.
Rigidbody에서 지원되는 함수 몇 가지만 알아보겠습니다.
매개변수로 입력되는 x, y, z축 방향으로 물리적인 힘을 가합니다.
입력이 반복될수록 적용되는 힘이 누적됩니다.
x축은 좌우(←→) 힘 (음수 값(-)은 왼쪽(←)으로, 양수 값(+)은 오른쪽(→)으로)
y축은 상하(↑↓) 힘 (음수 값(-)은 위(↑)로, 양수 값(+)은 아래(↓)로)
z축은 전후(앞뒤) 힘 (음수 값(-)은 앞으로, 양수 값(+)은 뒤로)
// x축으로 10의 힘을 가함
object.AddForce(10, 0, 0);
// y축으로 -5의 힘을 가함 (위로 5만큼 이동)
object.AddForce(0, -5, 0);
// z축으로 20의 힘을 가함 (앞으로 20만큼 이동)
object.AddForce(0, 0, 20);
매개변수로 입력되는 축의 물리적인 회전력을 가해주는 기능입니다.
x축은 좌우(←→) 회전 (오른쪽(→)으로 향할 때 양수(+), 왼쪽(←)으로 향할 때 음수(-))
y축은 상하(↑↓) 회전 (위쪽(↑)을 향할 때 양수(+), 아래쪽(↓)을 향할 때 음수(-))
z축은 전후(앞뒤) 회전 (앞쪽을 향할 때 양수(+), 뒤쪽을 향할 때 음수(-))
// 객체에 x축으로 10의 회전력을 가함 (오른쪽으로 회전)
object.AddTorque(10, 0, 0);
// 객체에 y축으로 -5의 회전력을 가함 (상향으로 회전)
object.AddTorque(0, -5, 0);
// 객체에 z축으로 20의 회전력을 가함 (전방으로 회전)
object.AddTorque(0, 0, 20);
게임 오브젝트에 가해지고 있는 물리력입니다.
3차원 벡터(x, y, z)로 구성되어 있어, 객체가 특정 방향으로 얼마나 빠르게 이동해야 하는지를 나타냅니다.
Rigidbody 컴포넌트가 있는 객체에만 적용됩니다.
public class MoveObject : MonoBehaviour
{
public Rigidbody rigid;
public float speed;
void FixedUpdate()
{
// 객체를 앞으로 speed 만큼 이동시킴
rigid.velocity = transform.forward * speed;
}
}
게임 오브젝트에 가해지고 있는 회전력입니다.
물체가 단위 시간 동안 얼마나 많이 회전했는지를 나타냅니다.
벡터량이기 때문에 크기와 방향을 모두 가지며, 주로 회전축을 중심으로 한 회전량을 나타냅니다.
public class RotateObject : MonoBehaviour
{
public Rigidbody rigid;
public float rotationSpeed
void FixedUpdate()
{
// 객체를 z축을 중심으로 회전
rigid.angularVelocity = Vector3.up * rotationSpeed;
}
}
[SerializeField] Rigidbody rigid;
[SerializeField] float power;
private float xInput;
private void Update()
{
xInput = Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
// 1. 힘 가해주기
rigid.AddForce(Vector3.right * xInput * power, ForceMode.Force);
// 2. 속도 설정하기
rigid.velocity = Vector3.right * power * xInput;
// 3. 회전력 가해주기
rigid.AddTorque(Vector3.up * xInput * power);
rigid.angularVelocity = Vector3.up * xInput * power;
}

오브젝트의 질량(무게)을 말합니다.
값이 클수록 힘을 가해도 덜 움직이고 충돌 시 질량이 큰 오브젝트가 덜 밀립니다.
하지만 질량이 더 크다고 해서 중력이 더 세게 작용하진 않습니다.
(이건 공기저항의 영향이 더 큽니다)
공기 저항을 말합니다.
값이 높을수록 떨어지는 속도가 느려지고 오브젝트가 더 빨리 멈춥니다.
회전 저항을 말하는 것이며, 회전 속도를 감속시키는 값을 말합니다.
즉, 값을 높게 하면 오브젝트가 회전하다가 더 빨리 멈추게 됩니다.
물리 계산 시 사용하는 질량 중심을 자동으로 계산할지 여부를 판단합니다.
대부분의 경우 켜두지만 직접 물리 구현이 필요할 때는 꺼서 수동 설정이 가능합니다.
물리 계산 시 관성을 자동으로 계산할지 여부입니다.
Automatic Center Of Mass 마찬가지로 대부분의 경우 켜두고 작업합니다.
이것 역시 직접 물리 구현이 필요하다면 수동으로 설정할 수도 있습니다.
중력을 적용하는 설정입니다.
해당 설정을 끄면 오브젝트가 떨어지지 않습니다.
Is Kinematic을 켜면, 해당 Rigidbody는 물리 엔진에 영향을 받지 않습니다.
즉, 중력, 충돌로 인한 반동, AddForce(), velocity 같은 물리적 힘을 받지 않도록 하는 설정입니다.
하지만 Collider는 여전히 존재해서 OnTriggerEnter()를 이용한 충돌 판정은 가능합니다.
정해진 길만 따라가는 NPC를 구현 할 때 바닥이나 벽 같은 충돌 감지는 필요하지만
충돌 반동 때문에 정지해 있거나 엉뚱한 곳으로 가는 부분을 방지 할 수 있습니다.
프레임 사이의 위치 보간(보완)을 통해 움직임을 부드럽게 만들어주는 설정입니다.
| 옵션 | 설명 |
|---|---|
| None | 보간 없음 (기본) |
| Interpolate | 이전 프레임과 현재 프레임 사이를 보간 |
| Extrapolate | 다음 프레임을 예측해서 부드럽게 처리 |
Rigidbody의 움직임 또는 회전을 잠그는 옵션으로 물리엔진에 제약사항을 겁니다.
제약은 축별로 Position과 Rotation을 고정할 수 있습니다.
쿠키런에서 쿠키가 물리엔진 때문에 넘어지면 안되잖아요? 그 때 일부로 제약을 거는 겁니다.
충돌 처리 역시 게임에서 빠질 수 없는 중요한 부분입니다.
OnCollisionEnter(Collision other)
OnTriggerEnter(Collider other) // Enter : 충돌이 실행될 때 1회 실행됩니다.
OnCollisionStay(Collision other)
OnTriggerStay(Collider other) // Stay : 충돌이 유지되는 동안 반복적으로 실행됩니다
OnCollisionExit(Coliision other)
OnTriggerExit(Collider other) // Exit : 충돌이 종료될 때(벗어나는 순간) 1회 실행됩니다.
Collision은 물리적인 충돌을 처리합니다.
두 개의 오브젝트가 부딪히면서 생기는 물리 반응을 보여주는 함수입니다.
사용하기 전에 무조건 IsTrigger 옵션이 꺼져 있어야 하고,
자신과 충돌 대상 모두에 Rigidbody 컴포넌트가 추가되어 있어야 하며,
두 Rigidbody중 하나는 IsKinematic이 체크 해제되어 있어야 합니다.
private void OnCollisionEnter(Collision collision)
{
Debug.Log($"{collision.gameObject.name}와 충돌했다");
}
private void OnCollisionStay(Collision collision)
{
Debug.Log($"{collision.gameObject.name}와 충돌 중");
}
private void OnCollisionExit(Collision collision)
{
Debug.Log($"{collision.gameObject.name}와 충돌이 끝났다");
}
게임에서 아래와 같이 활용할 수 있습니다.
✅ OnCollisionEnter
바로 데미지를 받아야 하는 경우
✅ OnCollisionStay
마법공격으로 그 주위에서 접촉시 계속 데미지를 받는 경우
✅ OnCollisionExit
런 게임에서 떨어질 경우 공중에서 점프를 못하도록 제한할 경우
Tirgger는 물리 반응 없이 오브젝트 간의 겹침을 감지하는 방식입니다.
일단 Collider의 IsTrigger가 선택되어 있어야 합니다.
IsTrigger 선택시 해당 오브젝트는 물리적인 충돌이 진행되지 않고 통과됩니다.
자신이나 충돌 대상중 하나에 Rigidbody가 꼭 필요하며,
둘 다 Rigidbody가 있는 경우에만 한쪽에 isKinematic으로 가능합니다.
문에 가까이 가면 자동으로 열림, 아이템 습득, 함정 발동 등
주로 특정 장소 도달 등의 상황에 사용됩니다.
private void OnTriggerEnter(Collider other)
{
Debug.Log($"{other.gameObject.name} 영역에 들어왔다");
}
private void OnTriggerStay(Collider other)
{
Debug.Log($"현재 {other.gameObject.name} 영역에 있다");
}
private void OnTriggerExit(Collider other)
{
Debug.Log($"{other.gameObject.name} 영역에서 나갔다");
}