로봇 시뮬레이션에서 중력과 충돌 처리는 물리 기반 상호작용을 현실감 있게 구현하는 데 필수적인 요소이다. Unity는 강력한 물리 엔진을 제공하여 이러한 요소들을 손쉽게 다룰 수 있게 해준다. 이 장에서는 Unity에서 중력을 설정하고 충돌을 처리하는 방법에 대해 상세히 다루겠다.
중력 설정
Unity의 물리 엔진은 기본적으로 중력을 지원하며, 이를 통해 로봇과 환경 간의 상호작용을 자연스럽게 구현할 수 있다. 중력은 Physics
설정을 통해 조절할 수 있다.
중력의 기본 개념
중력은 모든 물체에 작용하는 힘으로, 지구에서는 보통 \mathbf{g} = \begin{pmatrix} 0 \\ -9.81 \\ 0 \end{pmatrix} m/s²의 값을 갖는다. Unity에서는 이 값을 통해 시뮬레이션 내의 모든 물체에 동일한 중력 효과를 적용한다.
Unity에서 중력 설정 방법
- Physics 설정 열기:
- 상단 메뉴에서
Edit
>Project Settings
를 선택한다. -
좌측 패널에서
Physics
를 선택한다. -
중력 값 조정:
Gravity
항목에서 \mathbf{g} 값을 설정할 수 있다.- 기본값은 \begin{pmatrix} 0 \\ -9.81 \\ 0 \end{pmatrix} 이지만, 필요에 따라 변경할 수 있다.
csharp
// 예제: 중력을 사용자 정의 값으로 설정
Physics.gravity = new Vector3(0, -9.81f, 0);
- 중력의 방향과 크기 변경:
- 중력의 방향을 변경하여 예를 들어, 수평 방향으로 중력을 적용할 수 있다.
csharp
// 수평 방향으로 중력 설정
Physics.gravity = new Vector3(-9.81f, 0, 0);
물체별 중력 적용
기본적으로 모든 Rigidbody
컴포넌트가 중력의 영향을 받는다. 특정 물체에만 중력을 적용하거나 중력을 무시하려면 Rigidbody
설정을 조정해야 한다.
- 중력 무시하기:
csharp
// Rigidbody 컴포넌트에서 중력 무시 설정
Rigidbody rb = GetComponent<Rigidbody>();
rb.useGravity = false;
- 중력 강도 조절: 특정 물체에 대한 중력의 영향을 조절하려면 추가적인 스크립트를 작성하여 힘을 가할 수 있다.
csharp
void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
Vector3 customGravity = new Vector3(0, -4.905f, 0); // 절반 중력
rb.AddForce(customGravity, ForceMode.Acceleration);
}
충돌 처리
충돌 처리는 로봇과 환경 간의 물리적 상호작용을 정의하며, 이를 통해 로봇의 움직임과 반응을 현실감 있게 시뮬레이션할 수 있다. Unity는 다양한 충돌 감지 메커니즘을 제공하여 이를 지원한다.
충돌 감지의 기본 원리
Unity에서는 Collider
와 Rigidbody
컴포넌트를 통해 충돌을 관리한다. Collider
는 물체의 형태를 정의하고, Rigidbody
는 물리적 속성을 부여한다.
- Collider 종류:
- Box Collider: 직육면체 형태
- Sphere Collider: 구 형태
- Capsule Collider: 캡슐 형태
-
Mesh Collider: 임의의 메시 형태
-
Rigidbody:
- 물리 엔진의 영향을 받는 물체에 부여
- 중력, 질량, 마찰력 등을 설정 가능
충돌 감지 설정
- Collider 추가:
- 게임 오브젝트에 적절한
Collider
를 추가한다. -
예를 들어, 로봇의 각 부위에
Box Collider
를 추가하여 충돌을 감지할 수 있다. -
Rigidbody 추가:
- 충돌 반응을 원한다면
Rigidbody
컴포넌트를 추가한다. -
Rigidbody
의Is Kinematic
속성을 설정하여 물리 엔진의 영향을 받을지 여부를 결정한다. -
충돌 감지 이벤트:
- 스크립트를 통해 충돌 이벤트를 처리할 수 있다.
csharp
void OnCollisionEnter(Collision collision)
{
// 충돌 시 처리할 로직
Debug.Log("충돌 발생: " + collision.gameObject.name);
}
충돌 물리 설정
충돌 시 물체 간의 반응을 조절하기 위해 물리적 속성을 설정할 수 있다.
- 마찰력(Friction):
- 물체 표면 간의 마찰을 설정한다.
Physic Material
을 생성하여Dynamic Friction
과Static Friction
값을 조절한다.
```csharp // Physic Material 설정 예제 PhysicMaterial mat = new PhysicMaterial(); mat.dynamicFriction = 0.5f; mat.staticFriction = 0.5f; mat.frictionCombine = PhysicMaterialCombine.Average;
// Collider에 Physic Material 적용
Collider collider = GetComponent
- 탄성(Energy):
- 충돌 시 물체가 반발하는 정도를 설정한다.
Physic Material
의Bounciness
값을 조절하여 반발력을 설정할 수 있다.
csharp
// 탄성 설정 예제
mat.bounciness = 0.3f;
mat.bounceCombine = PhysicMaterialCombine.Maximum;
충돌 처리 최적화
충돌 감지는 시뮬레이션의 성능에 큰 영향을 미칠 수 있으므로, 최적화가 필요하다.
- 충돌 체커 최소화:
-
불필요한 충돌 체커를 제거하고 필요한 부분에만
Collider
를 추가한다. -
충돌 레이어 사용:
Layer
를 설정하여 특정 레이어 간의 충돌을 비활성화할 수 있다.
csharp
// 레이어 충돌 설정
// Edit > Project Settings > Physics > Layer Collision Matrix에서 설정
- Collider 간소화:
- 복잡한 메시 콜라이더 대신 기본 도형 콜라이더를 사용하여 계산 부담을 줄이다.
연속 충돌 감지 (Continuous Collision Detection)
기본적으로 Unity의 물리 엔진은 불연속 충돌 감지(Discrete Collision Detection) 방식을 사용한다. 이는 프레임 간 물체의 위치를 확인하여 충돌을 감지하는 방식으로, 고속으로 이동하는 물체가 충돌을 놓칠 수 있는 단점이 있다. 이를 해결하기 위해 연속 충돌 감지(Continuous Collision Detection) 방식을 사용할 수 있다.
- 연속 충돌 감지의 필요성:
- 고속 물체의 충돌 누락 방지
-
더 정확한 충돌 반응 구현
-
설정 방법:
Rigidbody
컴포넌트의Collision Detection
속성을 변경하여 설정할 수 있다.
csharp
// Rigidbody의 충돌 감지 모드를 연속으로 설정
Rigidbody rb = GetComponent<Rigidbody>();
rb.collisionDetectionMode = CollisionDetectionMode.Continuous;
- 충돌 감지 모드:
- Discrete: 기본 설정, 성능은 좋으나 고속 물체에서 충돌 누락 가능
- Continuous: 고속 물체의 충돌을 보다 정확하게 감지
- Continuous Dynamic: 동적 물체에 대해 더욱 정밀한 충돌 감지
- Continuous Speculative: 예측 기반 충돌 감지로 성능과 정확도의 균형을 맞춤
트리거(Collider Trigger) 사용
Collider
컴포넌트의 Is Trigger
속성을 활성화하면 해당 콜라이더는 물리적 충돌 대신 트리거 이벤트를 발생시킨다. 이는 물체가 충돌했을 때 물리적 반응을 일으키지 않고, 스크립트를 통해 특정 동작을 수행하고자 할 때 유용하다.
- 트리거의 활용 예:
- 로봇이 특정 영역에 진입했을 때 경고 표시
- 아이템 수집
-
자동 문 열림
-
설정 방법:
Collider
컴포넌트의Is Trigger
체크박스를 활성화한다.
csharp
// 트리거 콜라이더 설정 예제
Collider collider = GetComponent<Collider>();
collider.isTrigger = true;
- 트리거 이벤트 처리:
트리거 이벤트는
OnTriggerEnter
,OnTriggerStay
,OnTriggerExit
메서드를 통해 처리할 수 있다.
```csharp void OnTriggerEnter(Collider other) { Debug.Log("트리거에 진입한 오브젝트: " + other.gameObject.name); // 추가 로직 구현 }
void OnTriggerExit(Collider other) { Debug.Log("트리거에서 벗어난 오브젝트: " + other.gameObject.name); // 추가 로직 구현 } ```
충돌 레이어 및 충돌 매트릭스
충돌 레이어를 사용하면 특정 레이어에 속한 물체 간의 충돌을 활성화하거나 비활성화할 수 있다. 이는 시뮬레이션의 성능을 최적화하고, 불필요한 충돌 계산을 줄이는 데 유용하다.
- 레이어 설정 방법:
-
레이어 추가:
- 상단 메뉴에서
Edit
>Project Settings
>Tags and Layers
로 이동한다. - 원하는 레이어를 추가한다.
- 상단 메뉴에서
-
게임 오브젝트에 레이어 할당:
- 게임 오브젝트를 선택하고, 인스펙터 창에서
Layer
드롭다운을 통해 할당한다.
- 게임 오브젝트를 선택하고, 인스펙터 창에서
-
충돌 매트릭스 설정:
Edit
>Project Settings
>Physics
에서Layer Collision Matrix
를 조정하여 어떤 레이어 간의 충돌을 활성화할지 설정할 수 있다.
- 예를 들어, 로봇과 환경 레이어 간의 충돌만 활성화하고, 로봇 간의 충돌은 비활성화할 수 있다.
물리 성능 최적화 팁
-
단순한 콜라이더 사용: 복잡한 메시 콜라이더 대신, 가능한 한 기본 도형 콜라이더(Box, Sphere, Capsule 등)를 사용하여 계산 부담을 줄이다.
-
콜라이더 수 최소화: 필요한 부분에만 콜라이더를 추가하고, 불필요한 콜라이더는 제거한다.
-
물리 업데이트 주기 조절:
Fixed Timestep
을 조정하여 물리 업데이트의 빈도를 최적화할 수 있다. 이는Edit
>Project Settings
>Time
에서 설정할 수 있다. -
충돌 레이어 활용: 위에서 설명한 레이어 매트릭스를 활용하여 불필요한 충돌 계산을 줄이다.
-
LOD(Level of Detail) 적용: 물체의 거리에 따라 콜라이더의 복잡성을 조절하여 성능을 향상시킬 수 있다.
예제: 로봇과 지면 간의 충돌 처리
로봇이 지면과 충돌하여 안정적으로 서 있을 수 있도록 설정하는 예제를 살펴보겠다.
- 지면 설정:
- 평면(Plane) 게임 오브젝트를 생성하고,
Box Collider
를 추가한다. -
Rigidbody
컴포넌트를 추가하되,Is Kinematic
을 활성화하여 지면이 물리적 영향을 받지 않도록 설정한다. -
로봇 설정:
- 로봇 모델에
Rigidbody
와 적절한Collider
를 추가한다. -
Rigidbody
의Mass
,Drag
,Angular Drag
값을 설정하여 로봇의 물리적 특성을 조절한다. -
충돌 감지 스크립트 추가:
- 로봇에 스크립트를 추가하여 충돌 시 특정 동작을 수행하도록 설정한다.
```csharp using UnityEngine;
public class RobotCollision : MonoBehaviour { void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Ground")) { Debug.Log("로봇이 지면과 충돌하였다."); // 추가 로직 구현 } } } ```
- 테스트 및 조정:
- 시뮬레이션을 실행하여 로봇이 지면에 안정적으로 서 있는지 확인한다.
- 필요에 따라
Rigidbody
및Collider
설정을 조정하여 원하는 동작을 구현한다.