Unity handles collision between GameObjects with colliders, which attach to GameObjects and define the shape of a GameObject for the purposes of physical collisions. A collider is invisible, and does not need to be the exact same shape as the GameObject’s mesh. A rough approximation of the mesh is often more efficient and indistinguishable in gameplay.
가장 간단한(그리고 프로세서에 부하를 주지 않는) 콜라이더는 기본 콜라이더 타입입니다. 3D에서는 박스 콜라이더, 스피어 콜라이더, 캡슐 콜라이더가 바로 이 타입입니다. 2D에서는 박스 콜라이더 2D와 써클 콜라이더 2D를 사용할 수 있습니다. 복합 콜라이더 를 만들기 위해 이러한 콜라이더를 단일 게임 오브젝트에 원하는 만큼 추가할 수 있습니다.
복합 콜라이더를 사용하면 프로세서 부하를 낮게 유지하면서 게임 오브젝트의 대략적인 모양을 만들 수 있습니다. 유연성을 강화하기 위해 자식 게임 오브젝트에 콜라이더를 추가할 수도 있습니다. 예를 들어 부모 게임 오브젝트의 로컬 축을 기준으로 상자를 회전시킬 수 있습니다. 이런 식으로 복합 콜라이더를 만들 때에는 하나의 Rigidbody 컴포넌트 사용해야 하며 계층 구조의 루트 게임 오브젝트에 배치해야 합니다.
기본 콜라이더는 쉬어 변환이 일어난 경우 제대로 작동하지 않습니다. 로테이션과 불균일 스케일을 트랜스폼 계층 구조에서 모두 사용하여 결과적으로 형태가 더 이상 기본 형태가 아닐 경우 기본 콜라이더가 이를 정확히 나타낼 수 없습니다.
그러나 복합 콜라이더를 만들어도 충분히 정확히 표현하지 못하는 경우도 있습니다. 3D에서는 메시 콜라이더를 사용해서 게임 오브젝트의 메시 모양에 정확하게 맞출 수 있습니다. 2D에서는 폴리곤 콜라이더 2D가 스프라이트 그래픽 모양과 완벽히 일치하지 않지만, 원하는 디테일 수준(LOD)으로 모양을 다듬을 수 있습니다.
이러한 콜라이더는 기본형보다 프로세서에 훨씬 더 큰 부하를 주므로 꼭 필요한 경우에만 사용해야 합니다. 또한 메시 콜라이더는 다른 메시 콜라이더와 충돌할 수 없습니다(메시 콜라이더끼리 접촉해도 아무 일도 일어나지 않음). 이 문제를 피하기 위해 메시 콜라이더를 인스펙터에서 Convex 로 설정할 수 있습니다. 이렇게 하면 “볼록 다각형” 모양의 콜라이더가 생성되는데, 이는 원본 메시와 유사하지만 움푹 파인 부분이 전부 메워져 있습니다.
이 때의 장점은 컨벡스 메시 콜라이더가 다른 메시 콜라이더와 충돌할 수 있다는 점입니다. 따라서 적합한 모양의 움직이는 캐릭터가 있을 때 이 기능을 사용할 수 있습니다. 그러나 일반적으로 메시 콜라이더는 씬 지오메트리에 사용하고, 움직이는 게임 오브젝트의 모양은 복합 기본 콜라이더를 사용하여 유사하게 만드는 것이 좋습니다.
Rigidbody 컴포넌트 없이도 콜라이더를 게임 오브젝트에 추가하여 씬의 바닥, 벽, 기타 고정된 요소를 생성할 수 있습니다. 이러한 콜라이더는 정적 콜라이더라고 부릅니다. 이와 반대로, 리지드바디가 있는 게임 오브젝트의 콜라이더는 동적 콜라이더라고 부릅니다. 정적 콜라이더는 동적 콜라이더와 상호작용이 가능하지만, 정적 콜라이더에는 리지드바디가 없기 때문에 충돌에 리스폰스하여 움직이지는 않습니다.
콜라이더가 상호 작용할 때, 콜라이더의 표면은 각각이 나타내는 머티리얼의 프로퍼티를 시뮬레이션해야 합니다. 예를 들어, 얼음판은 미끄러워야 하고 고무공 표면은 마찰이 크며 탄성이 강해야 합니다. 충돌 중에 콜라이더의 형태가 변형되지는 않지만, 마찰과 탄성은 물리 머티리얼(Physics Materials) 을 사용하여 설정할 수 있습니다. 적절한 파라미터 값을 찾아내려면 약간의 시행착오가 필요할 수 있습니다. 예를 들어 얼음과 같은 미끄러운 머티리얼의 경우 0 또는 매우 낮은 마찰 값을 가지고, 고무와 같은 미끄럽지 않은 머티리얼은 높은 마찰과 거의 완벽한 바운스 값을 가집니다. 가능한 파라미터에 대한 디테일을 참조하려면 물리 머티리얼과 물리 머티리얼 2D 레퍼런스 페이지를 참조하십시오. 기존 이름을 함부로 바꿀 수 없어 물리 머티리얼의 3D 에셋의 영문명은 Physic Material(끝에 s가 없음) 이고, 2D의 영문명은 Physics Material 2D(끝에 s가 있음) 입니다.
스크립팅 시스템은 충돌이 일어나는 시점을 감지하고 OnCollisionEnter
함수를 사용하여 액션이 초기화할 수 있습니다. 또한, 단순히 하나의 콜라이더가 충돌을 일으키지 않고 다른 콜라이더의 공간에 들어가는 것을 물리 엔진이 감지하도록 할 수도 있습니다. 콜라이더를 트리거(Trigger)(Is Trigger 프로퍼티 사용)로 설정하면 이 콜라이더는 솔리드 오브젝트로 동작하지 않으며 그저 다른 콜라이더가 통과하도록 허용합니다. 다른 콜라이더가 이 콜라이더의 공간에 들어오면, 트리거는 트리거 오브젝트의 스크립트에 있는 OnTriggerEnter
함수를 호출합니다.
충돌이 일어나면 물리 엔진은 충돌과 관련된 오브젝트에 있는 모든 스크립트에서 특정 이름을 가진 함수를 호출합니다. 충돌 이벤트가 발생했을 때의 동작을 정의하기 위해 원하는 대로 코드를 작성할 수 있습니다. 예를 들어, 차가 장애물에 부딪쳤을 때 충돌 음향 효과를 재생하도록 할 수 있습니다.
충돌이 감지되었을 때 가장 먼저 일어나는 물리 업데이트는 OnCollisionEnter
함수 호출입니다. 접촉이 지속되는 상황에서는 업데이트 동안 OnCollisionStay
함수가 호출되며, 마지막으로 이 접촉 상태가 종료되었음을 나타내는 OnCollisionExit
함수가 호출됩니다. 트리거 콜라이더의 경우 유사하게 OnTriggerEnter
, OnTriggerStay
, OnTriggerExit
함수를 호출합니다. 2D 물리의 경우 동일한 기능을 하는 함수를 제공하며, 함수의 이름에는 예를 들어 OnCollisionEnter2D
처럼 위 함수명 끝에 2D 첨자가 붙습니다. 함수의 디테일과 코드 예시는 MonoBehaviour 클래스의 스크립트 레퍼런스 페이지를 참조하십시오.
노멀 비트리거 충돌에서는 충돌에 관여하는 최소한 하나의 오브젝트가 비키네마틱 리지드바디를 가져야 한다는 추가 조건이 있습니다(즉, Is Kinematic 이 꺼져 있어야 합니다). 두 오브젝트가 모두 키네마틱 리지드바디이면 OnCollisionEnter
등의 함수가 호출되지 않습니다. 트리거 충돌의 경우 이 제약이 적용되지 않으며, 따라서 키네마틱과 비키네마틱 리지드바디 모두 트리거 콜라이더에 들어가면 OnTriggerEnter
가 호출됩니다.
콜라이더는 Rigidbody 컴포넌트의 환경 설정에 따라 서로 다르게 상호작용합니다. 정적 콜라이더(즉, 리지드바디가 전혀 붙어있지 않음), 리지드바디 콜라이더, 키네마틱 리지드바디 콜라이더 등 세 가지 중요한 환경설정이 있습니다.
정적 콜라이더는 콜라이더가 있지만 리지드바디는 없는 게임 오브젝트입니다. 정적 콜라이더는 항상 같은 위치에 그대로 있으면서 절대로 움직이지 않는 레벨 지오메트리에 주로 사용됩니다. 리지드바디 오브젝트가 다가오면 정적 콜라이더와 충돌하지만 그래도 정적 콜라이더가 움직이지는 않습니다.
특정한 경우 물리 엔진은 절대 움직이지 않는 정적 콜라이더에 대해 최적화합니다. 예를 들어 정적 콜라이더 위에 놓인 차량은 이 정적 콜라이더를 움직여도 고정된 상태를 유지합니다. 물리 엔진 계산 속도에 별다른 영향을 주지 않고도 런타임 시점에 정적 콜라이더를 활성화 또는 비활성화하거나 이동시킬 수 있습니다. 또한 스케일이 왜곡되지 않고 일정한 경우에 한하여 정적 메시 콜라이더를 안전하게 스케일할 수 있습니다.
리지드바디 콜라이더는 노멀 비키네마틱 리지드바디와 콜라이더가 있는 게임 오브젝트입니다. 리지드바디 콜라이더는 물리 엔진에 의해 완전히 시뮬레이션되며 스크립트로부터 적용되는 충돌과 힘에 반응합니다. 다른 오브젝트(정적 콜라이더 포함)에 충돌할 수 있으며 물리를 사용하는 게임 내 가장 흔히 사용되는 콜라이더 설정입니다.
키네마틱 리지드바디 콜라이더는 콜라이더와 키네마틱 리지드바디가 있는(즉, 리지드바디의 IsKinematic 프로퍼티가 활성화됨) 게임 오브젝트입니다. 키네마틱 리지드바디 오브젝트는 Transform 컴포넌트를 수정하여 스크립트를 통해 움직일 수 있지만, 비키네마틱 리지드바디처럼 충돌이나 힘에 반응하지 않습니다. 키네마틱 리지드바디는 상황에 따라 움직이거나 활성화/비활성화되지만 그 외 상황에서는 정적 콜라이더처럼 동작하는 콜라이더에 사용해야 합니다. 예를 들어, 평소에는 움직이지 않는 물리 장애물처럼 동작하지만 필요할 때는 열 수 있는 미닫이문과 같은 경우에 사용합니다. 정적 콜라이더와 달리, 움직이는 키네마틱 리지드바디는 다른 오브젝트에 마찰을 가하며 따라서 접촉이 일어나면 다른 리지드바디를 “깨우게” 됩니다.
키네마틱 리지드바디 콜라이더는 움직이지 않고 있을 때에도 정적 콜라이더와는 다르게 동작합니다. 예를 들어, 콜라이더가 트리거로 설정되어 있으면 스크립트에서 트리거 이벤트를 받기 위해 리지드바디를 추가해야 합니다. 트리거가 중력의 영향을 받거나 물리 영향을 받지 않도록 하고 싶으면 해당 리지드바디의 IsKinematic 프로퍼티를 설정하면 됩니다.
Rigidbody 컴포넌트는 IsKinematic 프로퍼티를 사용하여 언제든 노멀 동작 또는 키네마틱 동작으로 변경할 수 있습니다.
좋은 예로 “래그돌” 효과가 있습니다. 래그돌의 경우 캐릭터는 일반적으로 애니메이션 하에서 움직이지만 폭발이나 큰 충돌 시 물리적으로 던져집니다. 캐릭터의 팔다리에는 IsKinematic 이 디폴트로 활성화되어 있는 각각의 Rigidbody 컴포넌트가 주어집니다. IsKinematic 이 활성화되어 있는 동안은 팔다리가 애니메이션에 의해 일반적으로 움직이다가, 비활성화되는 순간 즉시 물리 오브젝트처럼 동작하기 시작합니다. 이 시점에서 충돌력 또는 폭발력으로 인해 캐릭터는 팔다리가 현실처럼 마구 흔들리면서 날아가게 됩니다.
두 오브젝트가 충돌하면 이 오브젝트의 리지드바디의 환경설정에 따라 여러 다른 스크립트 이벤트가 발생할 수 있습니다. 아래의 표는 오브젝트에 있는 컴포넌트에 따라 어떤 이벤트 함수가 호출되는지를 구체적으로 나타냅니다. 일부 조합의 경우 두 오브젝트 중에서 하나만 충돌의 영향을 받으며, 일반적으로는 Rigidbody 컴포넌트가 없는 오브젝트에는 물리가 적용되지 않는 것이 원칙입니다.
충돌 시 충돌 검사가 되고 메시지가 전송됩니다 | ||||||
---|---|---|---|---|---|---|
정적 콜라이더 | 리지드바디 콜라이더 | 키네마틱 리지드바디 콜라이더 | 정적 트리거 콜라이더 | 리지드바디 트리거 콜라이더 | 키네마틱 리지드바디 트리거 콜라이더 | |
정적 콜라이더 | Y | |||||
리지드바디 콜라이더 | Y | Y | Y | |||
키네마틱 리지드바디 콜라이더 | Y | |||||
정적 트리거 콜라이더 | ||||||
리지드바디 트리거 콜라이더 | ||||||
키네마틱 리지드바디 트리거 콜라이더 |
충돌 시 트리거 메시지가 전송됩니다 | ||||||
---|---|---|---|---|---|---|
정적 콜라이더 | 리지드바디 콜라이더 | 키네마틱 리지드바디 콜라이더 | 정적 트리거 콜라이더 | 리지드바디 트리거 콜라이더 | 키네마틱 리지드바디 트리거 콜라이더 | |
정적 콜라이더 | Y | Y | ||||
리지드바디 콜라이더 | Y | Y | Y | |||
키네마틱 리지드바디 콜라이더 | Y | Y | Y | |||
정적 트리거 콜라이더 | Y | Y | Y | Y | ||
리지드바디 트리거 콜라이더 | Y | Y | Y | Y | Y | Y |
키네마틱 리지드바디 트리거 콜라이더 | Y | Y | Y | Y | Y | Y |