Unity3D2011. 6. 24. 16:03

 

Unity Web Player | performance_test

Posted by 버터백통
Unity3D2011. 5. 27. 10:20


[ 게임오브젝트와 이를 눈에 보이게 하기 위해 Attach된 4개의 클래스 ]
GameObject -> Object

유니티 모든 개체의 형태를 갖는 기본 클래스 : 아래의 컴퍼넌트를 갖는다.

Create Empty의 경우 Transform만 생성된다.

 

1 Transform -> Component

위치, 회전, 크기를 다루는 객체

 

2 MeshFilter -> Component

눈에 보이는 모형을 설정

 

3 Collider -> Component

모든 객체의 기본(최소) 입자,물체 단위

게임오브젝트의 물리적 영역을 결정

 

4 MeshRenderer -> Renderer

물체 표면에 렌더링하는 객체


 

[ Display와 무관한 물리적 작용과 동작(Event), 화면출력에 관여한 클래스 ]

-------------------------------------------------------------------------------------------

Component -> Object

GameObject attach할 수 있는 기본 클래스

대부분의 클래스가 Component를 취하고 있다.

-------------------------------------------------------------------------------------------

Behaviour -> Component

게임오브젝트가 동작할 여부를 활성 비활성 시키는 구성요소

변수로는 enabled만 선언되어있다.

 

MonoBehaviour -> Behaviour

모든 스크립트에서 파생되는 기본클래스

Start(), Awake(), Update(), FixedUpdate(), and OnGUI()등을 실행으로 스크립트로 객체를 제어한다.

-------------------------------------------------------------------------------------------

Rigidbody -> Component

물리 시뮬레이션을 통한 객체들의 위치제어

 

Camera -> Behaviour

플레이어에게 화면을 보여주는 장치

 

Light -> Behaviour

조명 효과를 내기 위한 구성요소의 스크립트 인터페이스


 

[ 유니티에서 출력]

 

********** PrintAndDebug

private var num = 1;

function Update () {

 

1 유니티 지원

Debug.Log("*********************************");


2자바스크립트에서 지원

print("return num :" + runCount() ); }

 

 

private function runCount():int

{

num++;

print("num with print : "+ num);

Debug.Log("num with Debug :" + num);

print("childCount :" + transform.childCount);

return num;

}

 

 

[ 변형1 ]

 

********** TranslateScript

public var speed:int = 0;

public function Update () {

변화가 없으면 실행되지 않는다.

print("myStaticVariable :" + RotateScript.myStaticVariable);

                                                                         

if( this.transform.position.x > 5 ){

speed = -1* speed;

}else if( this.transform.position.x < -5){

speed = -1* speed;

}

var nTmp:float = Time.deltaTime * speed;

                                        

 

//Translate( x , y, z );

this.transform.Translate( nTmp , 0, 0 );

}

 

 

********** RotateScript

public var speed:int = 0;

// Time.deltaTime사용여부

public var isDepandFrame:boolean = false;

public static var  myStaticVariable:int = 100;

 

function Update () {

if(isDepandFrame == true){

this.transform.Rotate(0,Time.deltaTime * speed,0);

}else{

this.transform.Rotate(0,speed,0);

}

}

 

[ 변형2 ]

 

********** LookAtScript  : Transform으로 제어
public var target : Transform;

public function Update() {

LookAt은 설정된 객체를 바라본다.

this.transform.LookAt(target);

}

 

 

 

********** LookAtScript  : GameObject 으로 제어

public var target2 : GameObject;

public function Update() {

if( target2 != null ){

Debug.Log("target2 :"+target2);

Debug.Log("target2 :"+target2.transform);

this.transform.LookAt(target2.transform);

}

}

 

컴퍼넌트 검색 ]

GetComponent는 객체에 attach된 컴퍼넌트로 접근한다.

attach를 포함하여 이 객체(Cube)는 한 개의 클래스로 간주한다.

GetComponent는 클래스에서 컴퍼넌트 조회에 사용되는 것이다.

 

>>>>목표

1 자신의 transform컴퍼넌트에 직접 접근하여 위치를 조정한다.

2 GetComponent를 사용하여 자신의 transform컴퍼넌트에 접근하여 회전한다.

 

********** GetComponentScript1

print("run GetComponentScript1");

this.transform.Translate(0, -1, 0);

this.GetComponent(Transform).Rotate(0, 50, 0);

 

 

>>>>목표

동일한 게임오브젝트(Cube)attach  다른 스크립트 또는 builtin 컴포넌트들을 찾을 수 있다.

큐브에 attach myOtherScript에 함수 myFunction()를 실행시킨다.

myFunction()의 리턴값은 int 100이다.

 

********** myOtherScript : attach된 스크립트, 실행할 함수 부분

public function myFunction():int

{

print("run myFunction");

return 100;

};

 

********** GetComponentScript2

function Update () {

print("run GetComponentScript2");

otherScript = GetComponent(myOtherScript);

print("return from otherScript.myFunction : " + otherScript.myFunction());

}


 

 

스크립트 컴퍼넌트 검색 ]

외부의 클래스에 선언된 변수에 접근하기 위해서는 static으로 선언되어있어야 한다.

아래의 변수 var01~var03까지는 variablesScript static으로 선언되었고 variablesScript는 어디에도 attach되지 않았다. 이 컴퍼넌트는 Cube attach되어있고 ownerScript에 의해 runMyFunc()가 실행된다.  리턴 값으로는 전달된 num의 값에 100을 더하여 건낸다.

 

>>>>목표

1 GetComponent()를 사용하여 외부 스크립트를 link

 

********** variablesScript : 변수만 선언된 스크립트, attach되지 않았다. 따라서 public static으로 선언

public static var var01:int = 100;

public static var var02:String = "String";

public static var var03:boolean = false;

 

 

********** myScript1 : 위부에 선언된 변수 접근 및 연산

public function runMyFunc( num:int ):int

{

print( "variablesScript.var01 :"+ variablesScript.var01);

print( "variablesScript.var02 :"+ variablesScript.var02);

print( "variablesScript.var03 :"+ variablesScript.var03);

return variablesScript.var01+num;

}

 

********** ownerScript : Cube attach myScript1 GetComponent()으로  otherScript link한다.

public var num:int = 0;

public function Update () {

var otherScript = GetComponent( myScript1 );

print( otherScript.runMyFunc(num) );

}

 

 


 

[ 게임오브젝트 검색 ]

 

inspector target을 설정하여 타겟 오브젝트에 회전을 가했다.

런타임 중 버튼을 클릭하여 target을 선택하도록 GameObject.Find()을 사용하여 객체를 검색 추출하였다.

 

********** runScript

public var target:Transform;

function Update () {

target.Rotate( 0, 1 , 0 );

print("target :"+target);

}

 

private var go:GameObject;

function OnGUI () {

 

aText = "Select Cube";

GUI.Label( Rect(10, 10, 300, 200), aText );

if( GUI.Button( Rect(10, 60, 200, 50), "Select Left Cube") ){

 go = GameObject.Find("Cube1");

target = go.transform;

};

 

if( GUI.Button( Rect(250, 60, 200, 50), "Select Right Cube") ){

go = GameObject.Find("Cube2");

target = go.transform;

};

}

 

 

키입력 체크 ]

 

********** InputTestScript

public  function OnGUI():void

{

print("OnGUI");

                                        

//키보드키 검색

if( Input.GetKeyDown( KeyCode.W ) ){

 

guiText.text = "You pressed the 'W' key";

}else if( Input.GetKeyDown( KeyCode.A ) ){

guiText.text = "You pressed the 'A' key";

}else if( Input.GetKeyDown( KeyCode.S ) ){

guiText.text = "You pressed the 'S' key";

}else if( Input.GetKeyDown( KeyCode.D ) ){

guiText.text = "You pressed the 'D' key";

}else if( Input.GetKeyDown( KeyCode.Space ) ){

guiText.text = "You pressed the 'Space ' key";

}

 

//마우스 버튼 검색

if( Input.GetMouseButton( 0 ) ){

guiText.text = "You pressed left click";

}else if( Input.GetMouseButton( 1 ) ){

guiText.text = "You pressed right click";

}else if( Input.GetMouseButton( 2 ) ){

guiText.text = "You pressed middle click";

}

}

 

 

이상 얼마전에 발표한 유니티3D 개발 1차 세미나 내용이였습니다~

Posted by 버터백통
이런저런 이야기2011. 5. 4. 17:23
원본 사이트 - 디자인과 플레이번역소


오늘 소개해드릴 글은 디자인과 플레이에 오랜만에 올라오는 실용적인 글입니다. 디자인과 플레이는 되도록 실용적인 노하우나 지식보단 이론과 철학, 사상을 담은 글을 전하는 게 기본 원칙인데요. 그래도 가끔은 일주일 안에 게임 프로토타입 만들기처럼 번역하지 않곤 못 참을 마력을 내뿜는 글이 있습니다.

오늘 저를 옭아멘 글은 바로, 인디 게임 개발자 데렉 유(Derek Yu)가 게임을 완성하지 못 하는 개발자들에게 제시하는 팁입니다. 데렉 유는 이터널 도터(Eternal Daughter)와 스펠런키(Spelunky), 그리고 동료 인디 개발자 알렉 홀로카와 함께 만든 아쿠아리아(Aquaria) 같은 게임으로 잘 알려져있습니다. 또 유명 인디 게임 블로그이자 커뮤니티인 TIG Source의 운영자이기도 하죠.

수많은 인디 개발자들의 작업을 지켜봤을 것이고, 스스로 여러 게임을 완성했고, 만들다 완성하지 못 한 게임도 많을 그에게, 게임 완성의 기술을 한 번 들어보지요 :)

2010년 9월 17일 | 데렉 유(Derek Yu) | 원문보기 (영어)

내 게임을 작업하면서, 프로젝트를 마무리한다는 것에 대해 많이 생각해봤다. 정말 재능 있는 개발자들이 게임을 마무리하는 데 어려움을 겪는 걸 많이 봤다. 솔직히, 나도 완성하지 못 한 게임이 줄줄이다...모두들 그럴 거라 생각한다. 물론, 어떤 이유로든간에 프로젝트가 전부 끝을 볼 수 있는 건 아니다. 하지만 가능성을 지닌 프로젝트를 포기하는 일이 계속된다면, 잠깐 뒤로 물러나 왜 그런 일이 일어나는지 생각해보는 게 좋을 것이다.

모두들 어떤 게임이나 만화, 영화를 두고 "와, 내가 하면 저것보단 낫지! 과대평가 쩐다"고 생각한 적 있을 것이다. 하지만 한 걸음 물러나 생각해보면 저 사람들은 프로젝트를 끝냈고 자신은 하지 못 했다. 적어도 한 가지 점에서는 나보다 그들이 더 낫고, 때문에 그 사람들은 내가 받지 못 하는 인정을 받는다! '완성하기'를 그냥 과정 중 한 단계가 아니라 기술로 생각하자. 더 잘할 수 있을 뿐 아니라 앞으로 나가는 데 필요한 습관이자 사고방식이다.

게임을 만드는 데 정해진 방식이 있진 않다. 게임 제작은 창조적인 활동이고, 거기에 깨질 수 없는 견고한 규칙 같은 건 없다. 하지만 다른 개발자들과 이 문제를 이야기해오다보니, 어느 지점, 특히 시작 지점에서 우리 모두 빠져버리는 정신적 함정이 있는 것 같다. 이 함정을 조심하는 것이 마무리의 첫 단계다. (내가 이 글을 쓰면서, 당신이 이 글을 읽으면서 생각을 정리하는 것도 그 단계다!)

그럼 이제 잔말은 그만 하고, 게임을 완성하는 열다섯 가지 팁을 보자.

1. 가능성 있는 아이디어를 선택하자

내 흥미를 돋는 게임에는 세 가지 유형이 있다. 바로 '내가 만들고 싶은 게임'과 '만들어졌으면 하는 게임', '내가 잘 만드는 게임'이다.

'만들고 싶은 게임'은 만드는 과정 자체가 진짜 재미있을 것 같은 게임이다. 실험하고 싶은 재미있는 메커닉일 수도 있고, 정말 움직이게끔 만들고 싶은 캐릭터일 수도 있다.

'만들어졌으면 하는 게임'은 만드는 것보다 만들어진 결과에 더 흥미가 가는 게임이다. '한 없는' 컨셉("GTA에다가 파이널 판타지에다가 스타크래프트에다가...")일 수도 있고, 구현이 재미있을 필요가 없는 단촐한 아이디어일 수도 있다.

'잘 만드는 게임'은 내 성격과 제작 경험에 잘 맞는 게임이다. 자연스럽게 끌리면서 그 리듬과 흐름을 아주 잘 이해하는 특별한 장르가 저마다 있을 것이다.

내 생각에, 적어도 완성될 가능성이 가장 높은 것은 이 세 범주 모두에 들어가면서 '실제로 이것을 만들 시간과 자원이 있는' 아이디어다.

2. 제발 진짜로 시작하자

아이디어를 적어놓는다고 게임이 시작되지 않는다. 디자인 문서를 써제낀다고 게임이 시작되지 않는다. 팀을 모은다고 게임이 시작되지 않는다. '시작할 준비'와 '시작'을 헷갈리지 말자. 기억하자. 게임은 플레이하는 것이다. 플레이할 수 있는 걸 만들지 않았다면, 그건 게임이 아니다!

그러니까, 꼭 게임 엔진을 만든다고 해도 시작되는 건 아니다. 이건 다음 팁으로 이어진다…

3. 쓸데 없이 기술 굴리지 말자

직접 엔진을 만드는 데는 장점과 단점이 있다. 자신에게 물어보자. 직접 만들어야 할 필요가 있나? 하고 싶은 게 이미 나와 있는 것으로는 불가능한가? 아니면 바퀴를 다시 발명하는 꼴인가? 물론, 직접 엔진을 만들면 입맛에 딱 맞게 게임을 만들 수 있다. 하지만 솔직해지자. 엔진을 만들고나서 실제로 게임 제작에 착수한 적이 몇 번이나 있나? 게임보다 게임 엔진에 손을 더 많이 대고 있지는 않은가?

나는 스펠런키의 원작을 게임 메이커로 만들었고, 그렇게 게임을 완성한 덕분에 엑스박스 360판을 만들 기회가 왔다. 그러니 게임 제작 소프트웨어나 단순화된 도구를 반칙이라고 생각하지 말자. 중요한 건 게임이다.

링크: TIG 포럼 기술 포럼

4. 프로토타입을 만들자

2번과 비슷하다. 일단 당장 쓸 수 있는 걸 갖다가 프로토타입을 만들자. 때로는 만들자마자 나쁜 아이디어를 가려내기도 한다. 때로는 뜻밖에 더 좋은 아이디어를 발견하기도 한다. 나는 보통 실제로 뭔가 만들기 전까지는 내가 뭘 만들고 싶은지 잘 모른다. 그러니 뭔가 만들자!

5. 핵심 메커닉이 재미있는지 확인하자

그저 갖고 놀기만 해도 재미있는 핵심 메커닉을 찾자. 가장 기본적인 상호작용을 수행하는 게 재밌어야 한다. 그게 플레이어들이 게임 내내 가장 많이 하게 될 것이기 때문이다. 궁극적으로, 이 핵심이 개발을 이끈다. 이렇게 하면 나중에 게임에서 필요 없는 부분을 잘라낼 때(13번) 일을 훨씬 쉽게 해준다. 이 핵심만은 항상 남겨둬야 한다.

프로토타입을 만들면서 처음 핵심 메커닉으로 생각한 것보다 더 재미있는 메커닉을 발견할 수도 있다. 그걸 새로운 핵심 메커닉으로 하는 것도 생각해보자!

6. 좋은 파트너를 선택하자 (없으면 할 수 있는 한 혼자 하자)

게임을 함께 만들 좋은 파트너를 찾는 건 데이트와 같다. 무슨 기술을 가졌는가가 중요하다고 생각할 수도 있다. "와, 난 프로그래머고, 저 녀석은 그래픽 디자이너네...그러니까 해보자고!" 하지만 아니다. 인성이나 경험, 타이밍, 상호 이해 등 생각해야 할 것이 더 있다. 연애와 마찬가지다. 어느 한 쪽만 헌신하는 관계가 되고 싶진 않을 것이다. 더 작은 프로젝트를 하면서 서로를 시험하자. 개발 몇 달 혹은 몇 년이 지나서 핵심인물이 손을 떼면 정말 치명적이다.

이건 완성된 프로젝트가 있는 게 또 좋은 이유다. 파트너가 당신이 뭘 할 수 있는지 알면 함께 일하기 더 편하게 생각할 것이다. 빛을 볼 수 있는 아이디어가 얼마나 적은지(그리고 실행되기 전까지 그 가치를 확인하는 게 얼마나 어려운지) 생각해보자. 아이디어만 가지고 경험 있는 사람을 설득하는 건 굉장히 어렵다. 좋은 파트너는 완성된 게임을 보고 싶어 한다. 그러니 완성하라!

아니면 온라인에서 무료 그래픽과 음악을 얻어보자(TIG에서 열리는 공모전을 통해 무료 아트와 음악이 많이 만들어진다). 필요하다면 ASCII를 쓰자. 나는 아티스트(그래픽 디자이너)기도 하기 때문에, 아무 것도 안 되어 있는 프로젝트보단 이미 될 것이 다 되어있고 그래픽만 빠져있는 프로젝트에 참여하고픈 마음을 안다. 코더가 필요한 거라면...직접 코드를 짜는 법을 배우거나(내가 할 수 있으니 당신도 할 수 있다!) 게임 제작 소프트웨어를 골라라(3번 참고).

7. 노가다는 일상, 계획에 넣자

게임 제작의 많은 부분은 철저하게 재미없고 따분하다. 놀이가 아니라 일이다(당신보고 "하루종일 게임만 한다"고 농담하는 사람은 목을 졸라줘야 하는 이유다). 언젠가는 계획과 프로토타이핑 단계에선 생각도 못 했던 것들(메뉴, 화면 전환, 저장하기와 불러오기 등)이 다가온다. "된장! 끝내주는 세계나 재미있는 메커닉을 생각했지...괴상한 기능 메뉴 만드는 데 몇 주를 보내려던 게 아니란 말이다!" 캐릭터 애니메이션처럼 조금은 재밌는 것도 100개의 캐릭터에 맞춰야 한다는 걸 깨달을 땐 악몽이 된다.

몇 번 그걸 경험하고 나면, 일단 프로젝트 규모를 예측해서 돌이킬 수 없는 수렁에 오래 빠지지 않도록 하는게 얼마나 중요한지 깨달을 것이다. 또 이 지루한 일들로 더 완성도 높은 게임을 만들 수 있다는 것도 깨닫는다! 가령 멋진 타이틀 화면은 게임이 그럴듯해 보이는 마법을 부린다.

8. 공모전 같은 행사를 진짜 마감일로 삼자

알렉과 내가 아쿠아리아를 작업할 때, 독립 게임 페스티벌의 제출 마감일은 우리의 방향성 문제를 결정하도록 종용했고, 스케줄을 더 현실적으로 보도록 해주었다. 그 마감일이 없었으면 우리가 완성이나 할 수 있었을지 모르겠다! 공모전의 마감일은 현실이다. 그리고 그 보상(인지도, 상품, 어쩌면 현금) 역시 아주 현실적이기 때문에 참가하는 게 좋다. 또한, 마음이 비슷한 사람들과 이어질 기회가 될 수도 있다.

링크: Independent Games Festival, Ludum Dare

9. 돌진하자

막힌 것 같은가? 놔두고 돌진하자. 다음 레벨, 다음의 적, 무엇이든 다음으로 돌진하자. 동기 부여 목적에도 도움이 되고, 게임 전체가 어떤 모습일지 감을 잡을 수도 있다. 글쓰기와 마찬가지다. 문장 하나하나 완벽한지 확인하면서 나아가고 싶진 않을 것이다. 먼저 윤곽을 그리자.

10. 몸과 마음의 건강을 돌보자

게임 만드는 데 집중하면서 자신을 돌보는 건 어려운 일일 수도 있다. 하지만 잠이나 운동, 적절한 식사를 거르고 게임을 만드는 건 해만 될 뿐이다. 잘해봐야 잠재력을 끌어내는데 방해가 되고 그만두고 싶은 마음만 더 들 뿐이다. 프로젝트에 의심을 갖는 건 자연스러운 일이지만, 우울감에 빠지거나 병을 얻는 것은 아니다. 몸과 마음이 똥덩어리 같으면 꿈꾸던 프로젝트도 관두고 싶어진다.

11. 다시 시작하는 데 변명하지 말자

"제 코드는 엉망진창입니다. 이번 프로젝트로 이미 많은 걸 배웠구요. 처음부터 다시 시작하면 더 좋게, 빨리 할 수 있어요. 게임도 더 빨리 나올겁니다!"

그만 하자. 아니다. 어떤 게임 개발이든 그렇다. 코드는 항상 엉망진창이 된다. 많은 것을 배운다. 절대 완벽할 수 없다. 그리고 처음부터 다시 시작하면, 다시 그 지점에서 정확히 똑같은 상황에 처한 자신을 발견한다. 이런 마음의 함정에 빠지는 건 끔찍한 일이다.

농담 하나 하자. 한 남자가 삶을 모조리 바쳐서 너무도 완벽한 게임 엔진을 만들었고, 남은 건 버튼을 한 번 눌러 완벽한 게임을 나오는 것 뿐이다. 사실, 농담이라고 보긴 좀 그렇다. 그 사람이 절대 끝내지 않았다는 부분이 웃긴 거니까! 그런 엔진이나 게임은 존재하지 않는다.

조직화가 나빠서 속도가 늦춰지는 거라면 돌아가서 수술을 하는 게 나을 것이다. 작동은 하는데 약간 더듬거리는 거라면, 용기를 내서 돌진하자!

12. 다음 게임으로 아껴두자

개발을 어느 정도 진행한 상태에서 모두를 매료시킬 아이디어가 떠올랐는데, 게임 전체를 다시 구현해야 한다고? 다음 게임을 위해 아껴두자! 안 그런가? 그게 삶의 마지막 게임도 아니고. 다음 게임을 위해 아껴두고...이번 것을 일단 완성하자!

13. 잘.라.내.라.

젠장, 일정에 한참 뒤쳐졌다. 좋은 생각이 왕창 있는데, 그 절반을 구현하기도 전에 화성 식민지가 먼저 완성될 것 같다. 아 비참해라...하지만 잠깐!

이건 사실 잘된 일이다! 이제 당신의 게임에 뭐가 정말 중요하고, 뭘 잘라낼 수 있는지 결정해야 하기 때문이다. 사실 우리 모두 자원과 시간이 무한하다면 모두 똑같은 쓰레기만 배출할테고, 그런 게임을 플레이할 이유가 없을 것이다. 자원과 시간의 유한함이 우리에게 목적이 있는 단단한 게임을 만들도록 압박한다.

재미있을 것 같은 핵심을 가지고 작업하는 거라면, 그 핵심의 가장자리에 다가갈 때까지 계속 잘라내자. 나머지 모두는 없어도 괜찮은 잔가지일 것이다. 최악의 경우에는 그 잔가지가 게임의 가장 좋은 부분을 가려버린다.

14. 그만 둔다면 다음에는 규모를 줄이자

그렇다, 때로는 그만 둬야할 때가 있다. 도저히 완성할 방법이 없고, 뭔가 잘라내기에도 너무 엉망일 수 있다. 팀의 다른 사람들은 이미 그만 뒀을지도. 내가 이 목록을 쓰는 건 이렇게 될 가능성을 피하도록 도와주는 거지만, 그런 프로젝트는 그만 둬야할 수도 있다. 때로는...그런 일이 일어난다.

구원할 가능성이 없다면, 적어도 다음 프로젝트는 규모를 줄이자. 눈을 높이는 건 쉽지만, 그와 동시에 프로젝트가 완성될 가능성은 더더 낮아진다. “내 기술은 발전했다! 실패에서 배웠다고."라는 게 참 흔한 변명이다. 이래서 완성하기를 기술로 보는 게 중요하다.

돌아가자. 당신의 능력을 밑돈다고 생각하는 지점까지 줄이고, 줄이고, 줄이자. 예를 들면, 우주 전략 게임에서 3D 우주 전략 게임으로 건너뛰지 말고, 우주 전략 게임의 한 가지 작은 요소에 집중하는 훌륭한 게임을 만들어 보자. 그걸 완성할 수 없다면, 아스테로이드 같은 것을 시도해보자. 그것만해도 생각했던 것보다 더 큰 고난일 (그리고 생각보다 만들기 재미있을) 가능성이 높다!

15. 마지막 10 퍼센트

마지막 10퍼센트가 진짜 90퍼센트라고들 한다. 실제로 디테일을 다듬는 게 시간을 꽤 먹는다. 일주일 안에 충분한 전투 시스템을 짰을지 모르겠지만...그걸 훌륭하고 복잡하게 (그리고 버그가 없게) 만드는 건...몇 달이 걸릴 수도 있다. 솔직하게 말하면, 진짜 마지막 바퀴에 들어서기 전에 '마지막 바퀴' 같은 전력질주를 여러 번 해야할 것이다.

위축되는 이야기로 들릴 수 있지만, 그렇지 않다. 마지막 10퍼센트가 괴로운 건 사실이지만, 개발기간 중 굉장히 만족을 느끼는 때이기도 하다. 그동안 시간을 헛되이 보내지 않았다면, 이 순간은 결국 모든 것이 “딱 들어맞는" 순간으로 다가온다. 질서 없이 늘어놓은 아이디어들과 콘텐츠가 달콤한 게임으로 바뀌는 순간은 마법 그 자체다.

모든 것은 디테일이다.

그리고 드디어...공개!

와따봉, 드디어 게임을 공개했군요! 축하합니다. 레벨업 하셨습니다. 완성의 보상: 자신감 상승, “프로젝트를 완성할 수 있는 사람” 칭호 획득, 게임 제작의 전체 과정을 모두 이해! 가장 좋은 건 당신의 게임을 내가 플레이하고 즐길 수 있다는 사실! 게임을 만드는 것만큼 하는 것도 좋아합니다.

이제 밖에서 기웃거리지 마세요. 당신은 게임 개발자입니다.

Posted by 버터백통