Game/Unity

[유니티] 프리팹(Prefabs)과 감지(Detection), 충돌(Collision) (2)

nowkoes 2023. 2. 1. 15:27

목표

- 프리팹의 개념을 이해하고 프리팹 인스턴스를 생성하기.

- 프리팹화된 몹들을 감지하기.


충돌(Collision)과 감지(Detection)

 게임을 하다 보면 몹의 특정 범위 내에 들어와서 공격을 받는 상황을 겪어보았을 것이다. 예를 들어보자. 타워 디펜스류 게임을 할 때 타워가 설치되고 몹을 인식하기 전까진 아무런 행동을 하지 않다가, 몹이 범위 안에 들어오면 공격을 하기 시작하는 것을 예로 들 수 있겠다. 이렇게 몹을 감지하고 공격하는 행동은 어떻게 해야 구현이 될까?

 

타워가 몹을 감지하고 공격하는 예시

 

 공격을 하기 위해선 몹을 감지하는 것이 우선이겠다. 여기서 감지(Detection)란 말 그대로 범위 내에 특정 오브젝트를 인식하는 것을 의미한다. 유니티에서는 감지를 하기 위해 자주 사용하는 것이 있는데, 바로 충돌(Collision)이다.

 

 

 앞서 보여준 짤에서 타워를 설치할 때, 타워 주위를 보면 하늘색으로 범위가 설정되어 있는 것을 알 수 있다. 우리는 이 범위에 해당하는 영역을 만들어, 다른 오브젝트가 이 영역과 충돌하는 순간 정보를 받아들이게 할 것이다. 

 

 마침 지난 시간에 사용한 경로를 따라가는 오브젝트를 생성해둔 프로젝트가 있으니, 이를 활용해보자. 여건 상 입체적인 모델링이 힘드니, 간단하게 파란색 큐브를 만들어 감지에 성공하면 Console창에 "Trigger Collision"을 출력하는 것을 목표로 진행해보자.

 

 

 다음 사진처럼 Tower라는 이름의 큐브를 만들어, 파란색 Material을 입혀주자. 우리가 충돌을 구현 하기 위해선 몇 가지 조건이 필요하다. 

  1. 두 오브젝트가 모두 Collider Component를 갖고 있어야 한다.
  2. 두 오브젝트 중 하나는 RigidBody Component를 갖고 있어야 한다.

 여기서 ColliderCollison 클래스의 변수로서 충돌 영역을 설정하는 컴포넌트고, RigidBody물리적인 시뮬레이션을 통해 물체의 위치 등을 조절하는 컴포넌트다. 

 

출처: docs.unity3d.com

 

 일반적으로 정적인 오브젝트와 동적인 오브젝트의 충돌을 구현할 땐, 움직이는 오브젝트에게 RigidBody 컴포넌트를 달아주는 편이다. 따라서 검은색 큐브와 파란색 큐브 모두 Collider를 달아주고, 검은색 큐브만 RigidBody 컴포넌트를 달아주자.

 

파란색 큐브(Tower)와 검은색 큐브(Model)의 프로퍼티

 

 이렇게 성공적으로 컴포넌트를 추가했다면 위의 사진과 같은 상황일 것이다. 여기서 Rigidbody에 Is Kinematic을 체크해주지 않으면 오브젝트가 물리 법칙의 영향을 받아 코드를 실행시켰을 때 여기저기 굴러다니는 현상이 일어나므로 체크를 해줘야 한다. 

 

 그리고 Is Trigger라는 부분은 Trigger 충돌을 일으킬 것인지에 대한 여부를 체크하는 부분이다. 우리는 단순히 감지하는 것이 목적이기 때문에 IsTrigger를 체크해두자. 이때 충돌의 종류에는 크게 Trigger와 Collision이 있다. 이때 Collision 충돌 물체가 서로 충돌했을 때 서로 밀어내는 함수고, Trigger 충돌물체가 서로 충돌했을 때 통과하는 함수다.

 

Collision vs Trigger

 

 작업을 완료하였으면 프리팹이 되어 있는 Model을 오버라이드 하여 모든 변경사항을 저장해두자.

 

 

 여기서 파란색 큐브가 검은색 큐브를 인식하는 방법이 여러 개가 존재한다. 먼저 파란색 큐브의 Collider 범위를 넓히는 방법과 콜라이더 배열을 만들어서 인지한 오브젝트를 이 배열 안에 초기화하는 방법 등이 있다. Collider의 범위를 넓히는 방법이 더 쉬워보이니, 다음과 같이 설정해보자.

 

Edit Collider를 눌러 콜라이더의 범위를 수정

 

 준비가 끝났으니, 충돌이 잘 이루어지고 있는지 확인하기 위해 파란색 큐브에 부착할 Tower 스크립트를 만든 후, 충돌이 일어났을 때 Console창에 "Trigger Collision"을 출력하도록 작성해보자. 이때 충돌하는 순간에 메시지를 출력할 것이므로 OnTriggerEnter() 함수를 이용하자. 

 

// Tower.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tower : MonoBehaviour
{
    public void OnTriggerEnter(Collider other)
    {
        Debug.Log("Trigger Collision");
    }
}

 

 이렇게 구현했을 때 예상되는 문제점이 하나 있다. 지금은 단순히 오브젝트가 큐브 두 개 밖에 없지만, 추후에 게임을 만들다 보면 많은 오브젝트들이 생겨날 것이다. 우리가 원하는 것은 검은색 큐브와의 충돌만 확인하고 싶은데, 다른 오브젝트와의 충돌도 감지할 것이므로 이를 구분해야할 것 같다. 따라서 우리는 Tag 기능을 이용하여 충돌했을 때 Tag가 BlackCube인 경우만 로그를 띄우도록 하자. 이 태그 기능은 유용하게 쓰이는 것 중 하나이니 사용 방법을 꼭 숙지하고 넘어가자.

 

 먼저 검은색 큐브의 Tag창에 Add Tag를 하여 태그를 추가해주고, 다시 검은색 큐브 창으로 돌아와 Tag를 BlackCube로 설정하자.

 

태그를 추가하고 설정해주는 과정

 

 그후 다시 스크립트 창으로 돌아가 충돌체의 태그를 비교한 후 로그를 출력하게 하자.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tower : MonoBehaviour
{
    public void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("BlackCube"))
        {
            Debug.Log("Trigger Collision");
        }
    }
}

 

 여기서 CompareTag부딪힌 물체 Collider other의 태그를 받아오는 함수다. 

 

출처: https://docs.unity3d.com/kr/530/ScriptReference/Component.CompareTag.html

 

 이렇게 적용을 했다면 다음 영상처럼 충돌 감지가 잘 될 것이다.

 

반응형