Physics 

Collider 컴포넌트로 충돌체크하기

 

작성 기준 버전 :: 2019.2

 

[본 포스트의 내용은 유튜브 영상을 통해서도 확인할 수 있습니다]

 

게임에서는 많은 것들이 충돌한다.

 

캐릭터가 총알이나 화살에 맞기도 하고, 달리던 자동차가 건물에 부딪히기도 하며 약간은 다른 개념으로 보안용 레이저에 도둑인 캐릭터가 감지되어 경보가 울리기도 한다.

 

이런 오브젝트의 충돌들을 처리하기 위해서는 물리적인 충돌을 처리하는 방법을 알아야 한다.

 

Collider 컴포넌트

 

유니티 엔진에서 Collider라는 컴포넌트를 이용해서 충돌을 체크한다.

 

 

유니티 엔진에서 가장 대표적으로 사용되는 콜라이더로는 Box Collider, Sphere Collider, Capsule Collider가 있다.

 

 

씬 뷰에서 Collider 컴포넌트가 붙어있는 게임 오브젝트를 선택해보면 위의 이미지와 같은 초록색 선으로 표시되는 영역이 보이는데, 이것은 Collider 컴포넌트가 충돌을 감지하는 영역의 크기를 보여준다.

 

Collider 컴포넌트의 프로퍼티

 

이번에는 각 Collider 컴포넌트의 프로퍼티들을 살펴보자.

 

우선 Collider 컴포넌트들은 공통적으로 Is Trigger 프로퍼티와 Material 프로퍼티, Center 프로퍼티를 가지고 있다. 하지만 이 중에서 Is Trigger와 Material 프로퍼티는 좀 더 뒤에서 설명하도록 하고 먼저 Center 프로퍼티부터 하나씩 살펴보자.

 

Center 프로퍼티와 그 아래에 있는 프로퍼티들은 콜라이더 영역의 위치와 크기를 조절하는데 쓰인다.

 

Center

 

 

먼저 Center 프로퍼티는 게임 오브젝트의 중심으로부터 어느 위치에 콜라이더의 중심을 둘 것인가를 설정한다. 위 이미지처럼  Y 값을 바꾸면 게임 오브젝트의 중심보다 위쪽에 약간 위쪽에 콜라이더 영역이 표시된다. 단 이때의 좌표 기준을 게임 오브젝트의 로컬 좌표를 기준으로 동작한다.

 

Box Collider의 프로퍼티

 

Center 아래의 프로퍼티들은 콜라이더의 종류마다 조금씩 다르니 하나씩 설명해보도록 하겠다.

 

Size

 

 

Box Collider의 Size 프로퍼티는 콜라이더 영역의 크기를 정하는데 쓰인다. Vector3 타입이며 xyz 각 값은 게임 오브젝트의 로컬 좌표계의 축에 일치하게 동작하며, 이 사이즈의 1 단위는 1 유니티 미터를 의미한다.

 

Sphere Collier의 프로퍼티

 

Radius

 

 

Sphere Collider의 Radius 프로퍼티 역시 콜라이더 영역의 크기를 정하는데 쓰이는데, 이 값은 구체의 반지름으로 동작한다. Radius를 1로 정하면 콜라이더 영역의 지름은 2유니티 미터가 된다.

 

Capsule Collider

 

Radius

 

 

Capsule Collider의 Radius 값은 콜라이더 영역의 두께를 정하는데 쓰인다. 참고로 이 값이 Height 값보다 커지면, 콜라이더의 영역이 Sphere Collider처럼 그냥 구체 모양이 되버린다.

 

Height

 

 

Height 값은 Capsule Collider의 길이를 정하는데 쓰인다.

 

Direction

 

 

Direction 프로퍼티는 Capsule Collider의 Height를 변경했을때 길어지는 방향을 정하는 프로퍼티다. 값으로는 X-Axis, Y-Axis, Z-Axis가 있는데, 단어 그대로 로컬 좌표계의 각 축의 방향을 따른다.

 

참고로 사람이 서있을 때의 모양이 위 아래로 길쭉한 모양이 일반적이기 때문에 사람 형태의 캐릭터에 콜라이더를 부착할 때는 Capsule Collider를 주로 사용한다. 그리고 뚱뚱한 캐릭터면 Radius 값을 늘려서 Capsule Collider의 두께를 두껍게하고, 키가 큰 캐릭터면 Height 값을 키워서 길이를 늘리는 방식으로 사용된다.

 

Is Trigger

 

그럼 이제 잠시 뒤로 미뤄두었던 Is Trigger 옵션을 보자. 이 옵션은 콜라이더가 트리거(Trigger)로 동작할지, 콜리전(Collision)으로 동작할지를 정하는 프로퍼티이다.

 

콜리전은 벽이나 바닥처럼 다른 물체를 통과하지 못하게 가로막는 장애물을 뜻하고, 트리거는 마트의 도난 방지 장치처럼 물체를 통과시키되 지나가는 물체를 감지하는 것을 의미한다.

 

 

Sphere 게임 오브젝트를 Cube 게임 오브젝트 위로 떨어지게 만든 뒤 Cube 게임 오브젝트가 가진 Box Collider의 Is Trigger 옵션을 켜둔 상태와 꺼둔 상태로 각각 플레이를 해보면 Is Trigger가 꺼져있을 때는 Sphere가 Cube위에 멈추고, 켜져있을 때는 Cube를 통과해버리는 것을 볼 수 있다.

 

 

참고로, 이렇게 게임 오브젝트가 중력과 같은 물리효과를 받게 하기 위해서는 Rigidbody 컴포넌트를 붙여줘야 한다.

 

Material

 

Material 프로퍼티는 콜라이더가 충돌할 때, 어떤 재료의 물리적인 특성을 보여줄 지를 설정할 수 있는 프로퍼티이다. 이런 종류의 머티리얼을 Physics Material이라고 하는데, 프로젝트 뷰에 우클릭하고 [Create > Physics Material]을 선택해서 생성할 수 있다.

 

 

오브젝트가 고무공처럼 튀는 것을 구현하기 위해 생성한 피직스 머티리얼에 여러가지 옵션이 있지만, 지금은 간단하게 Bounciness 옵션을 0.8로 변경하고 Bounce Combine을 "Maximum"으로 설정한다.

 

 

Sphere 게임 오브젝트의 Sphere Collider에 넣고 플레이 버튼을 눌러보면 아까 전에는 Cube 위에 얌전히 멈췄던 Sphere가 마치 고무공처럼 튀어오르는 것을 볼 수 있다.

 

Collider 충돌 감지하는 스크립트 작성하기

 

이제 이 충돌을 스크립트에서 감지하는 방법을 알아보자.


유니티 엔진에서는 콜라이더끼리 충돌했을 때, 특정한 함수를 호출해준다. 그런데 앞에서 Is Trigger 프로퍼티에 대해서 설명할 때, 이 옵션의 상태에 따라서 트리거와 콜리전으로 나뉜다고 이야기했던 것을 기억할 것이다.

 

유니티 엔진은 이 트리거와 콜리전이 충돌하는 경우를 다르게 취급하고 다른 함수를 호출해준다.

 

OnCollision 이벤트

 

public class ColliTest : MonoBehaviour

{

    // Collider 컴포넌트의 is Trigger가 false인 상태로 충돌을 시작했을 때

    private void OnCollisionEnter(Collision collision)

    {

        Debug.Log("충돌 시작!");

    }

 

    // Collider 컴포넌트의 is Trigger가 false인 상태로 충돌중일 때

    private void OnCollisionStay(Collision collision)

    {

        Debug.Log("충돌 중!");

    }

 

    // Collider 컴포넌트의 is Trigger가 false인 상태로 충돌이 끝났을 때

    private void OnCollisionExit(Collision collision)

    {

        Debug.Log("충돌 끝!");

    }

}

 

콜리전끼리 충돌했을 때는 OnCollision 계열의 이벤트가 호출된다. 충돌 과정은 3단계로 나눠서 호출되는데, 충돌이 시작할 때는 Enter, 충돌이 지속되는 동안에는 Stay, 충돌이 끝나는 순간에는 Exit가 호출된다.

 

private void OnCollisionEnter(Collision collision)

{

    // 이 컴포넌트가 부착된 게임 오브젝트의 콜라이더와 충돌한 게임 오브젝트 가져오기

    var obj = collision.gameObject;

    // 특정 컴포넌트 가져오기

    var component = collision.gameObject.GetComponent<SomeComponent>();

    // 콜라이더 가져오기

    var collider = collision.collider;

    Debug.Log("충돌 시작!");

}

 

이 콜리전과 충돌한 게임 오브젝트를 가져오기 위해서는 매개변수로 전달되는 collision에서 .gameObject 프로퍼티를 호출하면 된다. 그리고 .GetComponent 함수를 사용하면 이 게임 오브젝트에 부착된 컴포넌트를 가져올 수도 있다.

 

OnTrigger 이벤트

 

public class ColliTest : MonoBehaviour

{

    // Collider 컴포넌트의 is Trigger가 true인 상태로 충돌을 시작했을 때

    private void OnTriggerEnter(Collider other)

    {

        Debug.Log(other.name + "감지 시작!");

    }

 

    // Collider 컴포넌트의 is Trigger가 true인 상태로 충돌중일 때

    private void OnTriggerStay(Collider other)

    {

        Debug.Log(other.name + "감지 중!");

    }

 

    // Collider 컴포넌트의 is Trigger가 true인 상태로 충돌이 끝났을 때

    private void OnTriggerExit(Collider other)

    {

        Debug.Log(other.name + "감지 끝!");

    }

}

 

OnTrigger 이벤트 역시 Enter, Stay, Exit의 과정을 거친다. 이 OnTrigger 이벤트는 콜리전이 트리거에 닿았을 때, 콜리전과 트리거 양 쪽에서 모두 호출될 수 있고, 트리거와 트리거가 닿았을 때도 호출된다.

 

private void OnTriggerEnter(Collider other)

{

    // 이 컴포넌트가 부착된 게임 오브젝트의 콜라이더와 충돌한 게임 오브젝트 가져오기

    var obj = other.gameObject;

    // 특정 컴포넌트 가져오기

    var component = other.gameObject.GetComponent<SomeComponent>();

    Debug.Log(other.name + "감지 시작!");

}

 

OnTrigger 이벤트에서도 OnCollision 이벤트에서처럼 매개변수로 전달받은 Collider 타입의 other 변수를 통해서 감지한 게임 오브젝트와 거기에 부착된 컴포넌트를 가지고 올 수 있다.

 

기초적인 Collider의 사용법을 이해했다면 링크된 유튜브 영상을 통해서 이 Collider 컴포넌트의 기능을 응용해서 간단한 게임 기능을 구현하는 방법을 확인할 수 있다.

반응형

+ Recent posts