[Unity] 9. Collision & Trigger

치치·2025년 2월 26일
0

Unity

목록 보기
11/27
post-thumbnail

Polygon (폴리곤)

  • 기본적으로 다각형을 의미하며, 3D 모델링을 구성하는 기본요소이다. 대부분 여러개의 삼각형으로 구성된다
  • 유니티에서 다룰 때, mesh, vertex, 삼각형을 사용한다
  • 폴리곤의 수가 많을수록 렌더링 성능에 영향을 끼친다. -> 폴리곤 수를 최적화 하는 것이 중요!

ex)
같은 네모 모양 3D Object PlaneQuad의 연산량의 차이가 있는 이유

  • 폴리곤을 확인해보면 Plane의 폴리곤 수가 많은것을 확인할 수 있다
    -> Plane은 크기가 커질수록 정점의 수도 증가하게 된다

Plane : 주로 바닥이나, 지형에 사용
Quad : 창문에 사용


  • 즉, 폴리곤(삼각형)이 많으면 정점도 많아진다
  • 그만큼 드로우 콜이 많아지고, 렌더링에 연산량이 많이 들어가게 된다

드로우 콜 : GPU -> CPU로 이 오브젝트를 그려달라는 요청


참고: https://chlee200530.tistory.com/168


최적화 방법 (드로우 콜을 줄이고 성능 향상)

2D : 스프라이트 아틀라스 (Sprite Atlas)

  • 여러 개의 스프라이트(이미지)를 하나의 큰 텍스처로 합쳐서 사용하는 방법

3D : 정적 배칭 (Static Batching)

  • 움직이지 않는 오브젝트들을 하나의 큰 메시로 결합하여 드로우 콜의 수를 줄이는 기법
  • 정적 오브젝트는 시간 동안 변하지 않거나 이동하지 않는 오브젝트를 의미한다

3D : 동적 배칭 (Dynamic Batching)

  • 동적으로 움직이는 오브젝트들을 대상으로 드로우 콜을 줄이기 위해 자동으로 배치하는 방식
  • 유니티가 자동으로 배치를 수행하며, 주로 소형 오브젝트에 유용하다


충돌 처리 Collision

📌 충돌처리를 하기 위해서는 충돌 할 게임 오브젝트들에 collider 컴포넌트 추가, 한쪽에는 무조건 Rigidbody 컴포넌트 필요

📌 헷갈리지 말자

스크립트가 들어간 게임 오브젝트가 상대 게임 오브젝트와 충돌했을 경우, 호출되는 이벤트 함수이다
-> 매개변수로 들어오는 값은 충돌 된 오브젝트
-> Trigger도 동일하다


Rigidbody를 사용한 이동과 transform을 사용한 이동의 차이점

  • Rigidbody : 물리 기반의 움직임을 구현할 때 사용된다. 물리적인 힘, 충력, 충돌 효과로 객체가 이동하게 됨 - Rigidbody 컴포넌트가 연결된 게임 오브젝트의 위치를 나타내는 Vector3의 값

  • Transform : 객체가 물리 엔진에 영향을 받지 않으며, 직접적인 좌표 변경을 통해 이동한다 (순간적으로 위치를 바꿈) - 게임 오브젝트의 위치를 나타내는 Vector3의 값
    -> transform.position으로 오브젝트를 이동하는 경우, 모든 콜라이더들이 리지드 바디의 위치들을 재계산하여 갱신한다
    -> rigidbody.position으로 이동하는 것이 빠르다

이동하는 물체는 rigidbodycollider를 넣어주자 (성능 굳)

  • 부착된 Rigidbody 컴포넌트를 참조하여, 위치값을 바꾸는 Rigidbody.position 사용예시

Collider

  • 게임 오브젝트의 물리적인 상호작용을 처리하기 위해 사용되는 컴포넌트이다

  • 충돌을 감지하고 반응할 수 있고, 물리 충돌에 필수적인 역할

  • 콜라이더의 종류는 다양하게 있으니, 게임 오브젝트에 맞는 형태를 선택하는 것이 좋다

MeshCollider

  • mesh(모델)의 형태를 따라가는 콜라이더

  • 복잡한 형태의 모델을 사용하는 객체에 적합하다

  • Convex를 체크하면 메쉬가 잘 보인다 (삼각형)


Collision 이벤트 함수

  • 해당 스크립트(컴포넌트)가 부착된 게임 오브젝트를 기준으로 호출되는 것
    -> 매개변수로 들어온 collision이 충돌된 상대 오브젝트를 의미

  • 서로 충돌하면서 물리적인 이동이 발생
    -> 발생하지 않게 하려면 프로퍼티의 Freeze를 체크하자


OnCollisionEnter

  • 게임 오브젝트가 물리적인 충돌을 했을 때 호출되는 이벤트 함수

OnCollisionStay

  • 게임 오브젝트가 물리적인 충돌중일 때 호출되는 이벤트 함수

OnCollisionExit

  • 게임 오브젝트가 물리적인 충돌에서 벗어났을 때 호출되는 이벤트 함수

매개변수 Collision collision 의미

충돌한 오브젝트의 정보, 충돌 위치, 물리적 데이터 등을 포함한다 ex) gameObject, Transform, rigidbody 등

private void OnCollisionEnter(Collision collision)
{
    // OnCollisionEnter
    // 게임 오브젝트가 물리적인 충돌을 했을 때
    // 호출되는 이벤트 함수입니다.

    Debug.Log("OnCollisionEnter");

    if (collision.gameObject.CompareTag("Obstacle"))
    {
        Debug.Log(collision.gameObject.name);
    }
}

private void OnCollisionStay(Collision collision)
{
    // OnCollisionStay
    // 게임 오브젝트가 물리적인 충돌 중일 때
    // 호출되는 이벤트 함수입니다.

    Debug.Log("OnCollisionStay");

    if (collision.gameObject.CompareTag("Obstacle"))
    {
        Debug.Log(collision.gameObject.name);
    }
}

private void OnCollisionExit(Collision collision)
{
    // OnCollisionExit
    // 게임 오브젝트가 물리적인 충돌을 벗어났을 때
    // 호출되는 이벤트 함수입니다.
    Debug.Log("OnCollisionExit");

    if (collision.gameObject.CompareTag("Obstacle"))
    {
        Debug.Log(collision.gameObject.name);
    }
}

CompareTag

  • 게임 오브젝트를 분류하고 식별하는 데 사용되는 문자열

  • 인스펙터 창에서 태그 추가 & 지정 가능

  • Tagstring 자료형으로, Tag == "SomeTag"를 사용하면 비교 하는 대상의 문자열을 복사하여 매번 비교하기 때문에 복사비용 발생!!

  • CompareTag()

  • 복사 비용 없이 최적화된 성능을 유지

  • 성능상 유리하다

  • 원본은 bool 자료형으로, 매개변수로 넣은 값이 맞다면 true



슬리핑 모드

참고로만 알아두자 (물리엔진을 꺼버리는 기능)
-> 물리엔진은 연산량이 많이들어간다
-> 그래서 유니티 내에서 자체적으로 판단하고 끄는 경우가 있다
참고 : https://m.blog.naver.com/wolf5160/222539513751


Trigger 이벤트 함수

  • 게임 오브젝트의 isTrigger가 체크되어 있어야 한다

  • 두 오브젝트 중 하나에만 체크가 되어있어도 되기 때문에, 주로 배치되어 있는 오브젝트에 체크한다 (이동안하는거)

  • Trigger는 물리적인 충돌을 하지 않고, 단순 충돌 감지만 알려준다
    → isTrigger가 체크되어있는 오브젝트의 콜라이더와 충돌했는지를 감지 (물리적 충돌x)


private void OnTriggerEnter(Collider other)
{
    
    // OnTriggerEnter
    // 게임 오브젝트가 물리적이지 않은 충돌을 했을 때
    // 호출되는 이벤트 함수입니다.
    Debug.Log("OnTriggerEnter");
}

private void OnTriggerStay(Collider other)
{
    // OnTriggerStay
    // 게임 오브젝트가 물리적이지 않은 충돌 중일 때,
    // 호출되는 이벤트 함수입니다.
    Debug.Log("OnTriggerStay");
}

private void OnTriggerExit(Collider other)
{
    // OnTriggerExit
    // 게임 오브젝트가 물리적이지 않은 충돌을 벗어났을 때
    // 호출되는 이벤트 함수입니다.
    Debug.Log("OnTriggerExit");
}

참고 - 터널링(Tunneling) 현상

  • 주로 물리 엔진을 사용하는 게임에서 발생하는 문제로, 물체가 너무 빠르게 이동하거나 충돌을 처리할 때 충돌을 무시하거나 지나쳐버리는 현상

  • 두 게임 오브젝트에 콜라이더가 부착되어있고, 물리 충돌이 일어났지만, 너무 빨라서 뚫고 지나가는 현상

-> 근데 보통은 그렇게 까지 빠르게 이동하는 게임 오브젝트는 없기 때문에 자세히는 다루지 않겠다 (나중에)


profile
뉴비 개발자

0개의 댓글