게임 프로그래머가 처음 익히는 생각의 도구는 객체입니다. 이 수업에서는 코드를 쓰기 전에 로봇부터 설계했습니다. 로봇에게 필요한 능력치와 행동과 기억을 적어 보면 클래스의 변수와 메서드가 저절로 드러납니다.
2022년 1학기 한국애니메이션고등학교 2학년 「게임 개발과 미들웨어」 1강 「Unity 게임 개발 개론」에서 가르친 내용입니다.
게임 프로그래머는 무엇을 만드나
컴퓨터에는 운영체제(OS)가 있습니다. 운영체제는 하드웨어를 다루는 커널(Kernel)과 사람이 보는 화면(GUI)을 합친 것이고, 그 위에서 앱과 게임이 동작합니다. 게임 프로그래머는 운영체제 위에서 동작하는 프로그램을 만드는 응용 프로그래머입니다.
그렇다면 게임 안에는 무엇이 들어 있을까요? 수업에서는 게임을 나무처럼 펼쳐 봤습니다.
서버에는 NPC 와 몬스터가, 클라이언트에는 캐릭터와 건물이 있고, 캐릭터는 다시 무기와 상의를 가집니다. 이 사물들이 저마다 작은 생각(로직)을 갖고 움직입니다. 그래서 게임을 작은 생각이 모인 가상 세계라고 불렀습니다.
사물이 사물이 되려면

현실에서 로봇을 만드는 일은 전자 공학입니다. 모터를 달고 센서를 붙이고 배터리를 넣습니다. 게임 속 로봇은 컴퓨터 공학으로 만듭니다. 모터 대신 숫자를, 동작 대신 함수를 넣습니다.
수업의 질문은 이것이었습니다. 사물이 프로그램 속에서 사물이 되려면 무엇이 필요할까? 답은 세 가지입니다.

| 로봇에게 필요한 것 | 프로그램에서는 | 뜻 | 예 |
|---|---|---|---|
| 능력치 | 변수 (Attribute → Variable) | 그 사물이 가진 성질과 수치 | 최대 에너지, 팔 힘, 시야각 |
| 행동 | 메서드 (Behavior → Method) | 그 사물이 할 수 있는 일 | 걷는다, 집는다, 말한다 |
| 기억 | 데이터 (Data) | 움직이며 쌓이고 바뀌는 정보 | 다녀간 곳의 장애물 위치, 주인의 음성 명령 |
능력치와 기억은 둘 다 변수에 담기지만 성격이 다릅니다. 능력치는 로봇을 만들 때 정해지는 값이고, 기억은 로봇이 움직이면서 쌓이는 값입니다. 이 차이는 나중에 데이터베이스를 배울 때 기획 데이터와 실시간 정보의 차이로 다시 나옵니다.
실습: 로봇 전체를 설계하기
- 로봇에 필요한 능력치를 적어 보세요.
- 로봇이 할 수 있는 행동을 적어 보세요.
- 로봇의 기억에는 무엇이 있을까요? 예: 이동했던 지역의 장애물 좌표, 주인의 음성 명령어, 센서에 포착된 위험 지역
학생들이 함께 채운 답은 아래와 같습니다. 정답이 정해진 문제는 아니고, 많이 떠올릴수록 좋은 연습입니다.
능력치
기억 용량, 기억 속도, 몸무게, 최대 에너지, 저장된 에너지, 방전 속도, 왼팔 · 오른팔 힘, 악력, 왼다리 · 오른다리 힘, 왼 · 오른 무릎 최대 각도, 시력, 시야각, 머리 회전 각속도와 최대 각도, 허리 회전 각속도와 최대 각도, 프로세서 속도
행동
보고 있는 화면 저장, 기억 탐색, 걷는다, 달린다, 춤춘다, 점프한다, 멈춘다, 목을 돌려 바라본다, 허리를 돌려 바라본다, 팔을 뻗는다, 집는다, 놓는다, 말한다(기억을 찾아 대답한다)
기억
이동했던 지역의 장애물 좌표, 주인의 음성 명령어, 센서에 포착된 위험 지역
"말한다" 는 흥미로운 행동입니다. 로봇은 들은 말을 기억에서 찾아 대답합니다. "안녕", "다음에 봐", "무엇을 도와 드릴까요?", 알아듣지 못하면 "다시 말해 주세요". 행동이 기억을 읽어 쓰는 모습이 곧 메서드가 변수를 쓰는 모습입니다.
목록이 길어지자 다음 질문이 자연스럽게 나왔습니다. 이 많은 것을 모두 로봇 클래스 하나에 넣어야 할까?
실습: 부위로 나눠 설계하기
- 로봇의 머리에 필요한 능력치와 머리가 할 수 있는 행동을 적어 보세요.
- 로봇의 다리에 필요한 능력치와 다리가 할 수 있는 행동을 적어 보세요.
| 부위 | 능력치 | 행동 |
|---|---|---|
| 머리 | 기억 용량, 기억 속도, 탐색 속도, 회전 속도 | 기억한다(저장), 탐색한다(불러오기), 왼쪽으로 바라본다, 오른쪽으로 바라본다 |
| 다리 | 다리를 뻗는 힘, 다리를 굽히는 힘, 다리 길이, 발 길이와 폭 | 굽힌다, 편다, 걷는다, 달린다 |
부위로 나누면 각 부위는 자기 일만 알면 됩니다. 머리는 다리의 길이를 몰라도 되고, 다리는 기억 용량을 몰라도 됩니다. 몸통은 부위들을 모아 로봇이 되게 합니다. 이렇게 큰 사물을 작은 사물의 조합으로 만드는 것을 구성(Composition)이라고 합니다.
public class RobotHead
{
public int MemoryCapacity; // 기억 용량
public float MemorySpeed; // 기억 속도
public float SearchSpeed; // 탐색 속도
public float TurnSpeed; // 회전 속도
public void Remember(string data) { /* 기억한다 (저장) */ }
public string Search(string key) { /* 탐색한다 (불러오기) */ return null; }
public void LookLeft() { /* 왼쪽으로 바라본다 */ }
public void LookRight() { /* 오른쪽으로 바라본다 */ }
}
public class RobotLeg
{
public float StretchPower; // 다리를 뻗는 힘
public float BendPower; // 다리를 굽히는 힘
public float Length; // 다리 길이
public void Bend() { }
public void Stretch() { }
public void Walk() { }
public void Run() { }
}
public class Robot
{
public RobotHead Head = new RobotHead();
public RobotLeg LeftLeg = new RobotLeg();
public RobotLeg RightLeg = new RobotLeg();
}RobotLeg 클래스 하나로 왼쪽 다리와 오른쪽 다리, 두 객체를 만들었습니다. 클래스는 설계도, 객체는 설계도로 찍어 낸 실물입니다. 학생들이 클래스와 객체의 차이를 처음 손으로 느끼는 순간이 이 실습이었습니다.
게임 속 사물로 옮기기

로봇에서 연습한 방법을 그대로 MMORPG 에 옮겼습니다. 게임에 필요한 사물을 먼저 적고, 사물마다 능력과 행동을 적습니다.
| 사물 | 능력치 | 행동 |
|---|---|---|
| 플레이어 · 몬스터 | 생명력, 공격력, 방어력 | 이동한다, 탐색한다, 공격한다, 사망한다 |
| 무기 | 최소 공격력, 최대 공격력 | 타격할 때, 소모될 때, 착용할 때, 해제할 때, 강화할 때 |
| 탈것 | 이동 속도, 최대 보관 무게 | 걷는다, 달린다, 먹는다, 머리로 박는다, 앞다리를 든다, 소리친다, 잠잔다, 탈 때, 내릴 때 |
무기의 행동에는 "~할 때" 가 붙어 있습니다. 슬라이드에서는 On타격, On착용 처럼 적었습니다. 무기는 스스로 움직이지 않고, 무언가가 일어났을 때 불려서 반응합니다. 이런 함수를 이벤트 함수라고 하고 이름 앞에 On 을 붙이는 관례가 있습니다. Unity 의 OnTriggerEnter, OnClick 이 같은 모양입니다.
Public — 밖에서 부르는 것
- 탈것에 안장을 장착한다
- 달린다, 걷는다
- 공격한다, 사망한다
Private — 안에서 처리하는 것
- 발자국을 찍는다
- 깃털이 휘날린다
- 이동 속도를 다시 계산한다
마지막 연습은 Public 과 Private 를 나누는 것이었습니다. 다른 사물이 불러야 하는 행동은 Public 으로 열고, 발자국이나 깃털처럼 스스로 알아서 처리하는 연출은 Private 로 닫습니다. 닫아 두면 다른 사람이 그 클래스를 쓸 때 헷갈릴 일이 줄고, 안쪽을 고쳐도 바깥 코드가 깨지지 않습니다.
Unity 는 사물을 어떻게 만드나
수업 뒷부분에서는 이 생각이 Unity 에서 어떻게 쓰이는지 봤습니다. Unity 는 컴포넌트 기반으로 사물을 만듭니다.
GameObject
장면 안의 빈 사물입니다. 이름과 위치(Transform)만 가집니다.
Component
GameObject 에 붙여 능력을 더합니다. 모양을 그리는 Renderer, 부딪히는 Collider, 직접 짠 스크립트도 컴포넌트입니다.
Scene Graph
사물은 부모와 자식으로 이어집니다. 태양 → 지구 → 달처럼 부모가 움직이면 자식이 함께 움직입니다.
태양 · 지구 · 달 실습에서는 지구를 태양의 자식으로, 달을 지구의 자식으로 두고 각자 회전만 시켰습니다. 달은 자기 회전만 하는데도 지구를 따라 태양 둘레를 돕니다. 부모의 움직임이 자식에게 이어지기 때문입니다.
using UnityEngine;
public class Spin : MonoBehaviour // 컴포넌트가 되려면 MonoBehaviour 를 상속한다
{
public float degreesPerSecond = 30f; // 능력치: 인스펙터에서 고친다
void Update() // 행동: 매 프레임 불린다
{
transform.Rotate(0, degreesPerSecond * Time.deltaTime, 0);
}
}같은 Spin 컴포넌트를 세 사물에 붙이고 속도만 다르게 주면 됩니다. 로봇의 다리 클래스로 다리 두 개를 만든 것과 같은 생각입니다.
지금 100턴에서는
「졸업까지 100턴」의 캐릭터도 같은 생각에서 출발합니다. 캐릭터는 능력치와 상태를 갖고, 무엇을 할지는 바꿔 끼우는 행동 객체에 맡깁니다. 자세한 구조는 구조 읽기 4편에 정리했습니다.
정리
- 능력치, 행동, 기억. 사물을 이 세 칸으로 적으면 변수와 메서드와 데이터가 됩니다.
- 크면 나눕니다. 부위로 나누면 각자 자기 일만 알고, 같은 설계도로 여러 객체를 찍어 냅니다.
- 밖과 안을 가릅니다. Public 은 남이 부르는 행동, Private 는 스스로 처리하는 일입니다.
다음 편에서는 클라이언트 데이터베이스 SQLite 를 만들고 Unity 에서 읽는 실습을 다룹니다.