Unity

Collision(충돌)

gcreators 2024. 9. 23. 19:33

Collision은 일반적으로 두 개체가 충돌하는 상황을 말한다.

유니티에서는 Collision이라는 클래스가 있으며 두개의 게임 오브젝트가 충돌 했을 때 이 충돌의 이벤트 처리를 처리하는 클래스이다.

충돌에 대한 기준을 만들기 위해서

Collider라는 컴포넌트를 추가해야한다.

Collider는 Box, Sphere, Capsule 등 여러 형태로 구성되어 있다

오브젝트의 형태와는 상관 없이 Collider를 만들 수 있고

이런형태로 만들게되면 실제로 충돌되는 범위가 Box형태가 된다

Collider는 충돌의 경계를 설정하는, 감지를 위한 컴포넌트라고 이해하면 된다.

 

또한 유니티에서는 충돌 상황에서 두가지의 처리방법이 존재하는데

Trigger와 Collision 로 나뉜다

 

Trigger는

이 옵션에 체크가 되어 있어야 작동이 된다.

Trigger와 Collider는 충돌은 감지하는 공통점이 있지민

Trigger는 충돌시 물리적인 처리가 동작하지 않으며

Collision 는 충돌시 물리적인 이벤트 처리가 동작한다.

private void OnTriggerEnter(Collider _collider)
{
    Debug.Log("OnTriggerEnter: "+ _collider.name);
}

private void OnTriggerStay(Collider _collider)
{
    //Debug.Log("OnTriggerStay: " + _collider.name); // Stay : 충돌중일때
}
private void OnTriggerExit(Collider _collider) 
{
    Debug.Log("onTriggerExit: " + _collider.name);    
}

private void OnCollisionEnter(Collision _collision)
{
    Debug.Log("OnCollisionEnter: " + _collision.gameObject.name);
}
private void OnCollisionStay(Collision _collision)
{
    //Debug.Log("OnCollisionStay: " + _collision.gameObject.name);
}

private void OnCollisionExit(Collision _collision)
{
    Debug.Log("OnCollisionExit: " + _collision.gameObject.name);
}

Stay 메서드 같은 경우 활성화시 다른 충돌 상황의 확인이 어려워서 잠궈놨으니 따로 테스트를 권장한다.

다음 스크립트와 Collider를 추가한 후 Rigidbody라는 것을 추가한 게임 오브젝트를 준비한다.

Rigidbody는 유니티의 물리엔진과 관련된 것이라고 생각하면 된다

물리적인 속성을 추가해 힘, 중력, 충돌에 관한 물리적인 연산을 해주는 클래스이다.

Collider는 충돌의 경계를 설정하는 것이고

Rigidbody는 물리적인 속성을 추가하는 것 이고

Collision은 두 오브젝트가 충돌을 감지하고, 충돌시 일어나는 이벤트를 물리적인 처리하는 것 이다.

(Trigger는 두 오브젝트의 충돌은 감지하지만 물리적 처리가 동작하지 않는다.)

 

이제 Collider를 추가한 게임오브젝트 두개를 만든다

Collider를 추가한 게임오브젝트에 하나(스샷 기준 위 오브젝트)는 Is Trigger 옵션을 체크, 하나(아래)는 체크하지 않는다

 

다음과 같이 충돌 상황시 어떻게 동작하는지 확인이 가능하다.

 

Trigger같은 경우엔 오브젝트가 물리적인 처리를 하지 않아서 공이 관통하지만

충돌 자체는 인식하는 것을 보여주며

Collision 같은 경우엔 물리적인 처리를 해주어서 공이 관통하지 않는 모습을 확인 할 수 있다.

 

여기서 알 수 있는 것이 Trigger옵션은 충돌하는 두 오브젝트중 하나만 true여도 Trigger로 동작함을 알 수 있고

Rigidbody옵션 역시 하나만 물리 속성을 부여하면 Collision이 동작해 충돌 물리연산을 돕는 것을 확인 할 수 있다.

 

왜 둘중 하나만 되어도 동작이 되는지를 확인 했을까?

게임을 예시로 들었을 때

플레이어는 아이템, 필드 오브젝트, 몬스터, 그 외 여러가지 기믹이라 불리는 것들과 모두 상호작용이 이루어진다.

충돌처리가 이루어진다는 뜻이다.

그렇다면 이 충돌처리를 모두 플레이어에게 달아두면 되는가?

물론 그렇게 해도 되는 게임이 있겠지만 아닌 게임도 있을 것이다.

힐링 존이 설치된다면

게임 기획상 이 존에 있는 모든 hp를 가진 오브젝트들은 힐이 된다고 가정 했을 때

플레이어뿐만이 아닌 동료 npc, 그리고 몬스터 역시도 이 존에 들어온다면 hp가 회복이 되도록 설정 할 수도 있을 것이다.

그렇다면 위에서 말한대로 플레이어에 힐링 존을 만났을 때 hp회복을 넣어뒀다면

동료 npc에도, 몬스터에도 힐링 존을 만났을 때 hp회복에 관한 소스를 짜넣어야 할 것이다.

이렇게 되면 당연히 cost가 낭비가 된다. hp회복은 힐링 존에 설정을 해두는 것이 맞는 것이다.

 

반면 아이템의 휙득은 몬스터가 해선 안되니 플레이어 쪽에 넣어서 아이템을 휙득 할 수 있도록 해야할 것 이다.

 

이런식으로 필요한 곳에 적절한 상호작용(충돌처리)이 될 수 있도록 이 개념을 꼭 기억해둬야 한다.

 

 그리고

이런식으로 게임 오브젝트에 자식 오브젝트를 달게 되면

자식에서 처리 해야 할 일들이 있는데

이는 충돌처리 역시 똑같게 할 수 있다.

 

가장 최상위 부모에는 Rigidbody로 물리속성만 부여해준뒤

자식 오브젝트에는 필요한 만큼 collider를 추가하여 충돌 경계를 설정해준다

그리고

앞서 추가해둔 두개의 패널에 충돌시 Collider의 이름을 확인 할 수 있도록

두 가지 스크립트를 각각 게임오브젝트에 추가한다

public class TriggerPaddle : MonoBehaviour
{
    private void OnTriggerEnter(Collider _collider)
    {
        Debug.Log("TriggerPaddle Trigger: " + _collider.name);
    }
    private void OnCollisionEnter(Collision _collision)
    {
        Debug.Log("TriggerPaddle Collision: " + _collision.gameObject.name);
    }
}
public class CollisionPaddle : MonoBehaviour
{
    private void OnTriggerEnter(Collider _collider)
    {
        Debug.Log("CollisionPaddle Trigger: " + _collider.name);
    }

    private void OnCollisionEnter(Collision _collision)
    {
        Debug.Log("CollisionPaddle Collision: " + _collision.gameObject.name);
    }
}

 

 

이를 통해 알 수 있는 것은

Trigger는 충돌을 했을 때 충돌한 상대 오브젝트를 확인 할 수 있지만 

Collision은 Trigger옵션이 false일때 작동하므로 양쪽다 Collision상태라 자신만을 확인하고 동작함을 알 수 있다

이에 맞는 코드를 작성 할 수 있도록 기억하자

 

 

'Unity' 카테고리의 다른 글

Coroutine(코루틴)  (0) 2024.09.30
Prefab  (0) 2024.09.24
Transform(2) - position  (0) 2024.09.20
Transform(1) - 좌표  (0) 2024.09.20
충돌 처리(1) - AABB  (0) 2024.09.19