/ UNITY

Unity_초급학습_04

이 포스팅의 내용은 한빛미디어의 ‘레트로의 유니티 게임 프로그래밍 에센스(개정판)’을 요약 정리하였습니다.

Unity

링크 : 레트로의 유니티 게임 프로그래밍 에센스(개정판)

이번에는 유니티 엔진에서 상당히 중요한 개념으로 생각되는 컴포넌트에 대해서 알아볼 것이다.

SSAFY 과정에서 자바를 배우고 객체지향에 대한 이해도가 생겨, 상속의 의미와 장점에 대해서는 어느 정도 체득하였다고 생각한다. 하지만 유니티에서는 상속 관계도 물론 사용하지만 컴포넌트 패턴이라는 것을 사용하여 게임 오브젝트를 만들어낸다.

컴포넌트 패턴이란, 미리 만들어져있는 부품을 조립하여 완성된 오브젝트를 만드는 방식이다. 이 패턴에서 미리 만들어진, 조립에 이용되는 부품을 컴포넌트라고 부른다. 며칠 전 실습했던 큐브에 RigidBody 컴포넌트를 추가했다. 이것은 큐브라는 GameObject에 RigidBody라는 부품을 부착시켜 해당 오브젝트에 물리 개념을 부여했다.

이렇듯 유니티에서는 게임 오브젝트를 생성할 때 많은 양의 준비된 컴포넌트들 중에서 내게 필요한 기능을 찾아 해당 오브젝트에 추가하는 방식으로 원하는 오브젝트를 생성할 수 있다.

컴포넌트를 이용하는 것에는 이러한 장점이 있다.

  1. 유연한 재상용이 가능하다. : 상속만을 사용했을 때는 부모 클래스의 불필요한 기능까지 모두 상속받기 때문에 코드의 재사용이 힘들 수 있다. 컴포넌트 패턴을 이용하면 원하는 기능을 가진 컴포넌트만 선택적으로 골라서 사용할 수 있다.

  2. 기획자의 프로그래머 의존도가 낮아진다. : 기획자는 미리 만들어진 컴포넌트를 조립하여 게임 오브젝트를 만들 수 있다. 코드를 짜지 않고 객체를 생성할 수 있는 것이다. 이러한 기능들은 기획자의 프로그래머 의존도를 많이 낮춰주는 효과를 가진다.

  3. 컴포넌트의 특징인 독립성 덕분의 기능의 추가와 삭제가 용이하다. : 우리가 코드를 짜고, 또 수정할 때 일부의 코드만 변경해도 전체를 수정해야하는 상황이 생길때가 꽤 있다. 하지만 컴포넌트 패턴에서는 어떤 기능을 부착하고 제거할 때 다른 기능을 건드리지 않기 때문에 일부를 수정한다고 전체를 갈아엎어야 하는 일이 많이 줄어든다.

다음은 컴포넌트가 가진 독립성에 대한 이야기이다.

컴포넌트 패턴의 장점은 이 2가지 특징에서부터 나온다.

  1. 게임 오브젝트는 단순한 껍데기이다. 게임 오브젝트는 그 자체로는 특별한 기능이 없는 껍데기라는 것이다. 이러한 껍데기에 컴포넌트들이 부착되면서 하나의 객체가 완성되는 것이다.

  2. 컴포넌트는 각자의 기능이 자신 내부에 완성되어있기 때문에, 다른 컴포넌트에 영향을 주지 않고 독립적으로 작용한다. 따라서 게임 오브젝트에 어떤 컴포넌트를 추가하거나 제거한다고 해도 다른 컴포넌트에는 피해가 없다.

그렇다면 앞선 포스팅에서 만들었던, HelloUnity 프로젝트의 큐브를 다시 한 번 살펴보도록 하겠다.

Unity_01

HelloUnity 프로젝트의 큐브의 인스펙터 창이다. 큐브를 생성하기만 했는 데도, 새로 추가한 RigidBody를 제외해도 많은 컴포넌트들이 기본적으로 추가되어있다. 각 컴포넌트들의 기능은 다음과 같다.

  1. Transform : 게임 오브젝트의 위치, 크기, 회전상태를 지정한다.

  2. Mesh Filter : 오브젝트의 외곽선을 지정한다.

  3. Mesh Renderer : Mesh를 따라 색을 채워넣어 그래픽 외형을 그린다.

  4. Box Collider : 충돌판정과 관련된 컴포넌트로, 물리적인 표면을 만들어 다른 물체와 부딛힐 수 있게 한다.

  5. RigidBody : 게임 오브젝트가 물리엔진의 제어를 받게 한다.

큐브라는 게임오브젝트 자체는 아무것도 가지고있는게 아니고, 컴포넌트들이 해당 오브젝트에 계속해서 추가되어 현재의 큐브의 기능을 수행하고 있다고 생각하면 된다.

만약 여기서 Box Collider 컴포넌트를 제거한다면 어떻게 될까? 한 번 제거해보겠다.

Unity_02

컴포넌트의 점 세 개가 세로로 나열된 버튼을 클릭하고 remove Component를 클릭한다.

Box Collider이 사라져서 큐브는 물리적으로 충돌을 판정할 수 있는 표면이 사라졌다. 따라서 어떤 물체와도 충돌하지 않게 된다. 하지만, 그렇다고 RigidBody에서 설정한 중력이 사라지는 것은 아니기 때문에, 큐브는 바닥을 통과해 아래쪽으로 계속해서 떨어지게 된다.

Unity_03

충돌판정은 사라지고, RigidBody는 그대로 남아 저 아래로 떨어지는 큐브의 모습이다.

다음은 유니티의 모든 컴포넌트가 상속받는 MonoBehaviour 클래스에 대해서 이야기하겠다.

MonoBehaviour 클래스는 유니티에서 미리 만들어 제공하는 클래스이며, 컴포넌트에 필요한 기본 기능을 제공한다. 따라서, 유니티에서 게임 오브젝트에 컴포넌트로서 추가되기 위해서는 MonoBehaviour를 상속받아야만 한다.

앞서 컴포넌트 패턴을 설명할 때 컴포넌트들은 각각 독립적으로 작용한다라고 설명했다. 같은 게임 오브젝트에 속한다고 해서 컴포넌트 끼리 정보를 공유하거나 서로의 정보를 가지고 있지 않다는 말이다. 마찬가지로, 유니티 엔진에서도 모든 게임오브젝트에 대한 컴포넌트 목록을 가지고 있지 않다.

따라서, 유니티는 특정 컴포넌트의 특정 기능을 실행시키고 싶을 때, 해당 컴포넌트로 접근하는 것이 아닌 메시지를 브로드캐스팅 방식으로 날려보내는 방식을 사용한다.

네트워크를 접해본 사람이 있다면 익숙한 용어일 것이다. 의미는 비슷하다. 브로드캐스트는 보내는 쪽에서는 연결되어있는 모든 단말에 메시지를 보내고, 받는 쪽에서는 송신자 확인을 하지 않는다. 만약 해당하는 메시지가 단말에 맞는 메시지라면, 해당 단말은 메시지를 읽어들여 해당하는 기능을 수행한다.

예를 들면, 유니티의 게임 오브젝트에 Start() 메서드라는 게 있다. 해당 메서드의 코드는 해당하는 게임 오브젝트가 최초로 활성화 되는 때에 자동으로 한 번 실행된다. 개인적으로는 생성자와 비슷한 느낌이라고 생각한다. 그렇다면 어떻게 게임 오브젝트가 활성화될 때 start라는 메서드가 자동으로 실행되는 것일까.

유니티에서는 게임 오브젝트가 활성화 되면 그 게임 오브젝트에 start라는 메시지를 보낸다. 그러면 게임오브젝트의 컴포넌트에서 start 메서드가 있는 경우에는 수행, 그게 아니라면 무시하는 방식으로 start 메서드를 자동으로 실행할 수 있다.

유니티에는 위와 같이 이름과 철자만 똑같이 만들어두면 브로드캐스팅되는 메시지에 의해서 자동으로 실행되는 메서드들이 있다. 이러한 메서드를 유니티 이벤트 메서드라고한다.

오늘은 유니티에서 사용하는 컴포넌트에 대한 개념과 메시지 - 브로드캐스팅으로 이루어지는 컴포넌트의 기능 실행에 대해 알아보았다.