레트로의 유니티 게임 프로그래밍 에센스 - 3.1

Cosmos·2023년 3월 22일
0

학습 매체 : 책

책이름 : 레트로의 유니티 게임 프로그래밍 에센스

저자 : 이제민


본 내용은 해당 강의 내용을 공부하면서 정리한 글입니다.


3장 유니티 엔진이 동작하는 원리


이 장에서 다루는 내용

1. 상속을 이용한 개발 방법

2. 컴포넌트 패턴의 장점

3. 컴포넌트와 게임 오브젝트의 관계

4. MonoBehaviour의 정체

5. 메시지 기반 방식의 원리


3.1 상속과 재사용


  • 게임 엔진은 이미 완성된 기반 코드를 제공한다. 개발자는 게임 엔진의 코드를 '재사용'하므로 생산성이 올라간다.

  • 유니티의 컴포넌트 기반 구조를 이해하려면 코드를 재사용하는 전통적 방법인 '상속'을 알아야 한다. 상속은 이미 만들어진 클래스에 새로운 코드와 기능을 덧붙여 새로운 클래스를 만드는 방법이다.

  • 기초를 제공하는 클래스를 부모 클래스라 부르고 부모 클래스를 상속해서 확장한 클래스를 자식 클래스라고 부른다.

  • 클래스란 묘사할 대상과 관련된 코드(변수와 메서드 등)를 묶는 틀이다. 예를 들어, 플레이어 클래스는 플레이어와 관련된 코드를 가지고, 몬스터 클래스는 몬스터와 관련된 코드를 가진다.

class Monster {

	// 몬스터에 관환
    // 변수와 메서드들 ...
    
}

3.1.1 상속으로 몬스터 만들기

구현할 몬스터 클래스들

class Monster
class Orc : Monster
class OrcChieftan : Orc

  • 오크 클래스와 오크 대장 클래스뿐 아니라 몬스터 클래스까지 만든 이유와 클래스에서 콜론(:) 기호가 의미하는 바를 살펴보자.

  • 몬스터(Monster) 클래스 구현

class Monster

  • Monster 클래스는 몬스터로서 필요한 다음 필수 기능을 가지고 있다.
  1. 인공지능 기능

  2. 애니메이션 기능

  3. 공격과 방어 기능

  4. 물리 기능

  5. 기타 필수 기능

  • 그런데 Monster에는 제대로 된 외형이 없다. Monster 클래스의 역할은 게임 속 몬스터로 곧장 사용되는 것이 아니기 때문이다. Monster 클래스는 여러 종류의 몬스터 클래스를 구현할 때 필요한 기초를 제공하는 부모 클래스로 사용된다.

  • 게임에는 다양한 몬스터가 등장한다. 개발자는 이러한 '파생' 몬스터를 Monster 클래스를 '확장'하는 방식으로 만든다.


  • 몬스터를 기반으로 오크(Orc) 클래스 구현

class Orc : Monster

  • 위에서 콜론(:)부모 클래스를 상속해 왼쪽의 자식 클래스를 만든다는 의미이다.

  • 몬스터를 상속한 오크는 몬스터의 모든 기능을 가진다. 따라서 몬스터에서 이미 구현한 인공지능, 애니메이션, 공격과 방어, 물리 기능 등을 다시 구현할 필요가 없다.

  • 그래서 다음과 같은 오크 고유 기능만 구현하면 된다.

  1. 초록색 피부

  2. 오크의 애니메이션

  3. 오크의 스킬

  4. 그외 오크의 고유 기능


  • 오크를 기반으로 오크 대장(Orc Chieftan) 클래스 구현

class OrcChieftan : Orc

  • Orc 클래스를 상속해 OrcChieftan 클래스를 만든다. 오크의 모든 기능을 가진 오크 대장을 만들기 때문에 새로 구현할 부분이 많지 않다.

  • 그래서 다음과 같은 기능만 추가했다.

  1. 대장 모자

  2. 새로운 무기와 강력한 스킬

  3. 그외 오크 대장의 고유 기능

  • 상속을 이용하면 미리 만들어진 코드를 확장하여 새로운 코드를 작성할 수 있다. 이것이 상속의 힘이다. 하지만 상속이 만능은 아니다.

3.1.2 상속의 한계

  • 부모 클래스를 상속해 자식 클래스의 기초 구현을 대신할 수 있다. 하지만 상속에만 의존하면 오히려 코드를 재사용하기 힘들 수 있다.

  • 이번에는 RPG 게임에서 플레이어와 NPC, 몬스터를 만드는 예를 생각해보겠다.

  • 최상위 부모 클래스인 사람(Human) 클래스 구현

  • Human 클래스는 사람 형태를 가진 클래스의 부모 클래스로 사용한다.

  • 개발자는 사람 형태를 가진 오브젝트에 필요한 기능을 미리 예상해서 Human 클래스에 추가한다.


  • 플레이어(Player) 클래스 구현

  • 플레이어가 직접 조작하는 캐릭터인 Player 클래스를 만든다. Player 클래스는 Human 클래스를 상속하여 Human의 모든 기능을 가진다.

  • 지금까지는 문제가 없어 보인다.

  • NPC 클래스 구현

  • 마을 NPC는 한 곳에 머무르며 플레이어와 대화, 거래 등의 상호작용을 한다. 이번에도 Human 클래스를 상속하여 NPC 클래스를 만든다. 그런데 이 과정에서 문제가 생긴다.

  • NPC는 물리와 체력 기능이 필요 없다. 하지만, NPC 클래스가 상속한 Human 클래스에는 물리와 체력 기능이 있다. 결국, 개발자는 NPC 클래스에서 Human 클래스로부터 물려받은 물리와 체력 기능을 제거해야 한다.

  • 또한 제거한 기능과 관련된 다른 기능에 에러가 발생하지 않도록 코드를 정리하는 추가 작업도 해야 한다. 그 후 NPC 고유의 기능을 추가할 수 있다.

  • 상속으로 인해 오히려 추가 작업이 생겼다. NPC에는 Human의 일부 기능이 필요 없기 때문이다.


  • 몬스터(Monster) 클래스 구현

  • Human 클래스를 상속해서 Monster 클래스를 만든다. 이번에도 Human 클래스를 온전히 재사용할 수 없는 문제가 생긴다.

  • Human의 애니메이션 기능은 사람의 뼈대를 기준으로 만들어졌다. 하지만 몬스터는 슬라임이나 드래곤처럼 사람과 다른 뼈대를 가진 경우가 많다.

  • 애니메이션 기능 코드를 그대로 사용할 수 없어 기존 코드를 몬스터 형태에 맞게 다시 작성해야 한다. 또한 Human의 물리 기능이 비현실적인 움직임을 보여주는 몬스터와 맞지 않는다. 이 또한 다시 작성한다.

  • 이외에도 Human 클래스의 기능 중 몬스터와 어울리지 않는 것은 삭제하거나 수정한다. 그러고 나서야 몬스터 고유의 인공지능 기능이나 공격 기능 등을 추가할 수 있다.


3.1.3 결론

  • 상속에만 의존하면 오히려 기존 코드를 재사용하기 힘든 경우가 생길 수 있다.

  • 나중에 구현할 자식 클래스에 무엇이 필요한지 처음부터 정확하게 추측하기 힘들다. 또한 부모 클래스의 기존 기능이 나중에 구현한 클래스의 기능과 오히려 충돌할 수 있다.

  • 이외에도 상속에만 의존하면 기획자가 새로운 오브젝트를 만들 때 매번 프로그래머에게 부탁해야 하는 문제가 생긴다.

  • 이러한 문제를 해결하기 위해 컴포넌트 패턴을 사용한다.


다음 강의에서 계속~

profile
게임 개발을 목적으로 공부하고 있는 대학생입니다.

0개의 댓글