in 소프트웨어 개발

유니티 – OOP에서 컴포넌트/이벤트 위주 개발로.

포프님 영상을 보고 생각을 정리했다.

본래 예전 게임 개발에서는  OOP를 적용해서,

  1. 인간이란 상위 클래스를 만든다.
  2. 인간을 상속하는 개별 클래스들을 만든다.
    1. 몬스터
    2. NPC
    3. 플레이어
  3. NPC는 물리효과가 필요없고, 몬스터는 대화 기능이 필요없다. 플레이어는 추가 기능이 필요하다.
  4. 결국 비슷하지만 다른 요소가 추가될때 마다 상속받은 내용을 프로그래머가 새로 작성해줘야 한다.
  5. 아티스트와 기획자는 프로그래머 없이 뭘 할수 없다.

하지만 GDC2003 쯤에 컴포넌트 기반 게임 개발에 대해 논의가 됬는데,
프로그래머가 현실의 대상을 온전이 옮겨 오는게 아니라 , 현실의 대상을 보편적인 컴포넌트 요소로 쪼개서 나누어 놓으면 디자이너나 기획자가 원하는대로 조립하는 것이다.

위의 예시를 발전시키면, 인간을 물리, 대화기능, 공격기능 등의 컴포넌트로 쪼개고,

플레이어는 물리랑 대화 기능, 공격기능을 붙이고, 몬스터는 물리와 공격기눙, NPC는 물리가 필요 없으니 단순한 대화 기능만 붙이는 것이다.

유니티에서 다시 생각하면 이는, 게임 오브젝트에 컴포넌트를 조립하는 것이다.

유니티에서 게임 오브젝트란 단순한 컨테이너에 불과하다. 그리고 이 게임 오브젝트에 컴포넌트들을 조립하여 의미있는 대상을 만들어낸다.

그리고 유니티에서 스크립트라 부르는 코드들의 역할은 이 게임 오브젝트에 붙은 컴포넌트들의 레퍼런스를 가져와 제어하는 것이고. 이 방식은 디자이너가 프로그래머를 기다리지 않고 원하는 부품들을 조립해서 미리 배치하는 것을 가능하게 해준다.

만약 물리가 필요하면 해당 대상에만 쓰일수 있는 물리 코드를 작성하는 것이 아니라, 미리 준비된 리기드 바디 컴포넌트를 게임 오브젝트에 붙이면 물리를 가지게 되고, 충돌체 컴포넌트를 붙이면 해당 오브젝트는

컴포넌트 방식은, 조립을 가능하게 하기 위해 게임 오브젝트에 붙은 컴포넌트들이 서로에 대해 인지하지 못하는 상태다. 단순 컨테이너인 게임 오브젝트 또한 자기 아래에 붙인 컴포넌트들에 대해 상세히 알지 못한다.  그렇기에 이들은 이벤트 기반 방식으로 동작한다. 만약 충돌체 컴포넌트가 충돌을 감지하면 게임월드에 메세지를 뿌릴 것이다. 그것을 캐치해서 역으로 해당 오브젝트에 도달하여 충돌했을때 처리할 제어를 지시하는 것이고. C#이라 가능한 것이기도 하다. (물론 유니티의 뿌리는 C++이지만)

당연하지만 Start()와 Update() 같은 모노비에이비어에 달려오는 메서드 들도 다 이벤트 기반이다.

물론 쌩으로 게임월드에 이벤트를 날려대는이렇게 하는 것은 아니다. 브로드캐스팅은 비싸다. 하지만 근본은 그렇다는 것이다. 컴포넌트들은 독립적이며, 이벤트 기반이다.

아무튼 이런 방법으로 인해 발생하는 성능 손실에 비해 생산성에서 얻는 이익이 더 크기 때문에 컴포넌트/이벤트 개발은 주류가 된것이다. 언리얼도 그렇게 변했고.

유니티는 결국 프로그래머를 위한 툴이 아니라 디자이너를 위한 툴이라고 볼수도 있는 부분이다.

그렇지 않게 짤수도 있겠지만, 대부분의 경우 유니티 c# 코드는 그리 깊은 수준을 요구하지 않으며, 컴포넌트를 컨트롤 하는 목적으로 작성될테니.