꽃미남 프로그래머 김포프가 창립한 탑 프로그래머 양성 교육 기관 POCU 아카데미 오픈!
절찬리에 수강생 모집 중!
프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by 밥을먹는선비


0. 개요 혹은 잡설...


부족하지만 강좌를 하다 보니 4회군요. 

이번에는 코루틴 쪽 기본개념을 간단히 알아봐야겠네요. 


현실세계에서 인간이 무슨일을하다가 잠시 중단하고 다른일을하고 다시돌아와 하던일을 계속하는건 아주 자연스러운일입니다. 

이것을 프로그램으로 대입해서 생각하면 하나 이상의 함수 호출 엔트리포인트와 exit포인트를 가질수있다는 것입니다.

이부분은 사실 goto문을 남발하는 코딩과 별차이가 없다라고 생각할수도있습니다. 


Knuth 와 Dijkstra는 goto문을 두고 설전을 벌이신것으로 유명하신 분들입니다.

Dijkstra가 많은 업적을 남기셧지만 그중에 '갑'은 goto문을 쓰면 해롭다는 종교적인 신념을 만들어낸 것 입니다. 

(goto문이 선악의 기준이 되다니 얼마나 대단합니까?)


반면 Knuth는 goto문은 해로운것이 아니며 꼭 써야하는 경우도 있다며 반기를 드셨죠.

Knuth 가 하신말씀중에 '서브루틴은 코루틴의 특수한 형태이다.' 라는 말씀이 있습니다. 



1. 게임 로직의 핵심 상태 제어엔 FSM


게임프로그램에서 큰특징중 하나가 실시간 처리입니다. 다른 분야 프로그래머들이 게임 프로그래머로 전향을 할때 가장 어려운점이 어떻게 동시에 여러개의 움직임을 제어 할것인가 라는 문제입니다.

대부분 그런 질문은 'NPC AI를 어떻게 해요?' 제목으로 글을 많이 남깁니다. 

글을 올린 분의 사정을 자세히 들어보면 AI관련 내용이라기보단 이런 내용입니다.


'간단한 알피쥐게임을 만드는데요. 마을에 NPC들이 돌아다니는걸 어떻게 해야할지 모르겠어요?

씨로 다음과 같이 했거든요.'


게임오브잭트::생활하기() {

상점가기();

담배사기();

집으로가기();

}


게임루프() {

while( 게임종료되었나() ) {

전사.생활하기();

법사.생활하기();

}

}


'근데 한캐릭터가 생활을 하는동안 화면에 아무것도 움직이지않고 키보드 입력조차 받을수없는데 이것을 어떻게 해야죠?'


이러면 여러가지 답글이 달리게됩니다. 대부분 많은 분들이 FSM을 언급하시면서 대충 정리하자면 이런식으로 해라는 답변글이 올라오게 됩니다. 


게임오브잭트::생활하기() {

switch(단계)

{

case 1:

상점가기();

단계++;

case 2:

담배사기();

단계++;

case 3:

집으로가기();

단계 = 1;

break;

}

 

처음에 나온 로직이 아래와 같이 처리가 되었다면...

전사:상점가기() -> 전사:담배사기() -> 전사:집으로가기 -> 법사:상점가기() -> 법사:담배사기() -> 법사:집으로가기() 


새로운 후자에 나온 로직은...

전사:상점가기() -> 법사:상점가기()  -> 전사:담배사기()-> 법사:담배사기() -> 전사:집으로가기 -> 법사:집으로가기() 


게임루프상에서는 전사와 법사의 일을 번갈아나가며 처리를 하게됩니다. 두 오브잭트는 마치 동시간대에 존재하는것처럼 보이게됩니다.


머 사실 이것으로 충분하기는 합니다.


굳이 코루틴같은걸 굳이 써야하는건 왜일까요?

 

프로메테우스 영화에서 보면 인간이 있는데 왜 인간이 존재하는데 인간하고 똑같은 안드로이드를 굳이 왜 만든건지 물어보는 장면이 나오죠. 

답은 '할 수 있으니깐!'(물론 하고싶다고 다하고 살면 결과가 좋지 않다라는 교훈을 주기위한것같긴 합니다만....)


2. 양보하기 있긔 없긔?



일단 유니티 예제를 보도록 하시죠.


coroutin1.js 를 만들고 내용을 다음과 같이 코딩해줍니다.

#pragma strict


function Start () {

Debug.Log( gameObject.GetInstanceID()  + ": step1 ");

Debug.Log( gameObject.GetInstanceID() + ": step2 ");

Debug.Log( gameObject.GetInstanceID() + ": step3 ");

}


function Update () {

}


참고로...

소스에서 나오는 gameObject.GetInstanceID()는 현재 게임오브잭트의 고유한 아이디값을 가져옵니다.


그리고 wiz, wory 두개의 게임오브잭트를 만들고 방금 코딩한 스크립트를 연결시켜줍니다.


연결 시켜줍니다.


콘솔창에서 결과를 확인합니다.


일반적인 서브루틴이 호출이 만들어내는 당연한 결과가 출력이됩니다.


그럼 소스내용을 고쳐 봅시다.




step1 과 step2 사이에 yield를 추가해줍니다.






유니티에서 yield문은 말그대로 양보를 해줍니다. 어떤 서브 루틴을 실행을 하다가 yeild문을 만나면 서브루틴실행을 잠시 보류하고 서브루틴을 빠져 나옵니다. 그리고 이 서브루틴을 호출했던 부모서브루틴의 다음 라인을 실행합니다. 그리고 게임루프상에서 다음 턴이 오면 보류했던 위치 부터 실행을 재계합니다.



빨간색 선은 첫번째턴, 파란색은 두번째턴




호출한 함수(Start)보다 호출받은 함수(DoLiving)가 나중에 종료된다.



3. 코루틴 과 yield


코루틴은 단일쓰레드지만 마치 멀티쓰레드처럼 동작을합니다. 그러나 바늘과실(쓰레드의 어원))은 하나 이므로 이점은 유의를 하셔야합니다.

세마포어가 여러개의 바늘과 실을 일렬로 늘어놓아 마치 하나의 실과 바늘처럼 쓰도록 도와주는 것이라면 코루틴은 하나의 실과 바늘을 어지럽게 꼬아서 여러개의 바늘 과 실처럼 보이게 하는것입니다.


멀티쓰레드는 크게 두가지로 나누어지는데요. 선점형과 비선점형으로 나누어집니다.

비선점형의 특징이 프로그래머가 콘텍스트 스위칭 위치를 직접 정해줄때만 스위칭이 일어날 수 있다는 특징이 있습니다.

근데 바로 코루틴이라는게 비선점형 멀티쓰레드와 유사하고 차이점은 단일쓰레드라는 것입니다.


4. 결론


비선점형 멀티쓰레드의 단점중에 하나가 버그로인한 무한루프나 io작업오류등으로 블럭이 되면 그상태를 빠져나올수없다는 단점이 있습니다.

유니티는 그래서 아애 코루틴내의 루푸문에서 yield가 없으면 컴파일 에러가 뜨더군요. 아주 아주 실용적인 부분같습니다. 이런게 바로 유니티의 숨겨진 매력인듯합니다.


이번회에는 주로 yield를 예를 들어 설명을 했는데요 

다음회에는 StartCoroutine함수로 코루틴을 사용한 예제와 같이 더 설명을 하겠습니다.


참고자료 


http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html


요건 씨샵~

http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx


html5

http://stackoverflow.com/questions/2297286/javascript-check-yield-support



반응형
,
Posted by 알 수 없는 사용자

보통 통신을 할때에 메시지ID를 사용합니다.

보내는쪽과 받는쪽이 이 메시지ID로 구분하여 어떤것때문에 보냈는지를 알 수 있습니다.


namespace eMessage
{
enum Type
{
Test1,
Test2,
Test3,
...
};
}


그런데 문득 이런생각이 들었습니다. 

'메시지ID가 보내고 받는 데이터의 타입도 같이 가지고 있으면 좋겠다..'

그래서 만들어보았습니다.


struct MessageTable
{
Message<unsigned int> Test1;
Message<unsigned int, const Vector3&> Test2;
Message<int, const std::vector<int>&> Test3;
...
};

extern const MessageTable MessageType;


(네.. 저는 템플릿매니아..)

대충 이런식으로 선언을 하고 MessageType.Test1 이 메시지의 객체가 됩니다. 

'멤버변수의 초기화는 선언한 순서대로 초기화가된다' 라는 특성을 이용하여

MessageType.Test1.GetMessageID() 는 0

MessageType.Test2.GetMessageID() 는 1

MessageType.Test3.GetMessageID() 는 2

가 되도록 Message들의 가상 상위 클래스인 MessageBase에 static 변수를 하나 만들고 카운팅을 해주었습니다.


// MessageBase.h
class MessageBase
{
static unsigned short s_count;
...
};


// MessageBase.cpp
unsigned short MessageBase::s_count = 0;

MessageBase::MessageBase()
: m_messageID( s_count++ )
{
}


그러면 타입은 어떻게 가지고 있는걸까요?


template<typename D1=void, typename D2=void>
class Message : public MessageBase
{
public:
typedef D1 DataType1;
typedef D2 DataType2;

typedef typename type_traits::remove_cv<typename type_traits::remove_reference<D1>::type>::type DataBaseType1;
typedef typename type_traits::remove_cv<typename type_traits::remove_reference<D2>::type>::type DataBaseType2;
...
};


이쯤 보셨으면 도대체 이걸 어따가 쓰지? 하는 생각이 드실지도 모르겠는데요.. 저는 이런식으로 사용합니다.


template<typename T>
void SendMessage( const T& messageType, typename T::DataType1 d1 )
{
...
}


SendMessage( MessageType.Test1, 100 );

이렇게 호출하면 SendMessage 함수 안에서 컴파일타임에 메시지에서 사용하는 타입인지 체크가 가능합니다!


그런데 이런걸 만들면 도대체 뭐가 좋은거지?! enum은 메모리도 안먹는데!!

이건 메시지타입 하나당 메모리도 메시지ID의 타입만큼(예제에선 unsigned short)씩 먹자나!!

라고 하실 분들이 많으실텐데.. 전 편하게 쓰고 있습니다.....


편한것들 중 한가지를 말해보자면..

메시지ID가 데이터타입을 알고 있기 때문에 버퍼에 데이터를 넣거나 빼는것도 제공할 수 있습니다.


// MessageBase.cpp
void MessageBase::PushMessageID( std::streambuf& buffer, const MessageBase& messageType )
{
boost::archive::binary_oarchive oa( buffer, boost::archive::no_header );
oa <<  messageType.m_messageID;
}

void MessageBase::PopMessageID( std::streambuf& buffer, unsigned short& messageID )
{
boost::archive::binary_iarchive ia( buffer, boost::archive::no_header );
ia >> messageID;
}


// Message<D1, D2>
template<typename D1=void, typename D2=void>
class Message : public MessageBase
{
...
void Push( std::streambuf& buffer, DataType1 d1, DataType2 d2 ) const
{
boost::archive::binary_oarchive oa( buffer, boost::archive::no_header );
oa << d1;
oa << d2;
}

void Pop( std::streambuf& buffer, DataBaseType1& d1, DataBaseType2& d2 ) const
{
boost::archive::binary_iarchive ia( buffer, boost::archive::no_header );
ia >> d1;
ia >> d2;
}
};


SendMessage에서는 이렇게..


template<typename T>
void SendMessage( const T& messageType, typename T::DataType1 d1, typename T::DataType2 d2 )
{
if( m_pServerSession != NULL )
{
MessageBuffer buffer( 512 );
MessageBase::PushMessageID( buffer, messageType );
messageType.Push( buffer, d1, d2 );
m_pServerSession->Send( buffer );
}
}


받는 부분에선..


unsigned short messageID;
MessageBase::PopMessageID( messageBuffer, messageID );

...

int data1;
std::vector<int> data2;
MessageType.Test3.Pop( messageBuffer, data1, data2 );


이런식으로 사용하고 있습니다..

템플릿에 익숙하면 여기저기에서  유용하게 쓰일 수 있지만

템플릿을 안쓰는 분들이면 쓸곳이 없긴 하겠네요..

저는 템플릿 매니아..



반응형
,
Posted by 알 수 없는 사용자

안녕하세요. ozlael형님 보다 1년이나 젋은 랩좀비, 랩하는 좀비군입니다. 영계입니다(...)
오늘은 회사에서 일을 하다가 매우 눈에 거슬리는 함수를 발견해서, 그것을 좀 더 스무스하게 바꾼 경험에 대해서 얘기해 볼까합니다. 뭐 다들 알고 있는 것일 수도 있구요.

일단 다음과 같은 함수가 있었습니다.

CBaseObject* CWorld::GetIndexedObject(int index)
{
	int curIndex = 0;
	for ( auto iter = m_objectList.begin() ; iter != m_objectList.end() ; ++iter ) {
		if ( curIndex == index ) 
			return iter->second;
		++curIndex;
	}
	return nullptr;
}

이 함수의 문제점은 외부에서 컨테이너에 접근하기 위해서 0~m_objectList.size()까지 하나씩 접근하게 된다는 거지요. 그래서 오브젝트의 갯수가 10개 정도만 되도 55번의 계산을 반복하게 됩니다. 100개가 되면 5050개로 기하급수적으로 많아지게 되는 아름답지 못한 상황이 펼쳐집니다. 

아마 저렇게 구현이 된 이유가 vector가 아닌 list나 map이어서 그랬을 겁니다. vector라면 문제가 없죠. -캐쉬문제는 일단 넘어가고- 그냥 return 하면 되니까요. 그래서 어떤 방식으로 처리할까 고민하다가, 람다와 std::function을 통해서 나름 아름답게 처리가 되도록 변경하였습니다.

함수 본체는 이렇게 구현되고.. ...(std::function이 html을 방해해서 그냥 붙여 넣기)

void CWorld::ApplyFunctionToBaseObject( std::function<void(CBaseObject*)> Func )
{
std::for_each(m_objectList.begin(), m_objectList.end(), [&](std::pair<OBJHANDLE, CBaseObject*> objHandle) {
Func(objHandle.second);
});
}
이렇게 사용하도록 하였습니다.

void CView::OnUpdateDynamicObjectTitle( float elapsedTime ) { auto UpdateTitleGagueFunct = [=](CBaseObject* pBaseObject) //람다로 미니함수를 만듭니다. { pBaseObject->UpdateTitleGauge(elapsedTime); }; m_pWorld->ApplyFunctionToBaseObject(UpdateTitleGagueFunct); //람다를 넘겨주어서 컨테이너 안에서 계산하도록 합니다. }


우왕ㅋ굳ㅋ. 여러분 vs2010 사용하세요.
반응형
,
Posted by 김포프

요즘들어 Unity가 인기를 많이 끌고 있고, 저도 어쩌다 유니티를 주무르는 동안에 발견한 내용들을 짧게짧게 블로그에 올려볼 생각입니다. 유니티를 체계적으로 배우시고 싶다면 아마 게임개발포에버에서 도플광어님이 연재하시는 글을 보시는게 젤 좋을겁니다.


자, 그렇다면 오늘의 짧은 정보는... 과연 Unity는 어떤 언어로 작성되었나? 입니다. Unity가 Mono를 이용해서 .NET 프레임워크를 자체적으로 지원하고, 저희가 유니티에서 사용할 수 있는 스크립트 언어도 C# 이다보니


'유니티가 C#으로 작성 되었구나. 그럼 이 엔진이 속도가 너무 느리지 않을까?'


라는 걱정을 하는 분들이 계실겁니다. (저도 그랬다는..)


그래서 그에 대한 답을 좀 찾아보니 영문 질답란에 이미 유니티 개발자가 답을 해놨더군요.



이걸 대충 번역하면...


"유니티는 C++로 작성되었으나 다음과 같은 예외가 있습니다.


.NET API를 노출시켜서 여러분들이 C++로 게임을 짤 필요를 없게 만든 것 뿐이지요. 자바스크립트나 C# 또는 Boo를 이용해서 코딩을 할 수 있는 이유가 바로 .NET API 덕분입니다.


에디터 프로그램의 UI는 C#으로 작성했습니다. 유니티를 사용하시는 게임 개발자들에게 공개된 API와 거의 동일한 API를 쓰지요. (아직 공개되지 않는 API를 조금 쓰기도 합니다만 그리 많진 않습니다.)


이것이 바로 "UnityEngine.dll 파일을 다른 C# 프로젝트에서 사용할 수 있나요?"라는 질문에 대한 답이 언제나 "아니요"인 이유입니다. UnityEngine.dll에는 거의 아무 기능도 들어있지 않습니다. 이건 그저 C#/자바스크립트 호출들을 C++ 엔진에 연결해줄 뿐입니다. C++ 엔진이 없이는 그냥 속빈강정이랄까요?"




한마디로 대충 정리하면:

  • 유니티 내부는 C++이여서 C#보단 성능이 빠릅니다. 단, C#/C++ 컨텍스트 스위치 되는 부분에서 약간의 성능저하는 있을수 있습니다만 언리얼엔진에 비해 크게 문제는 안될거 같습니다.
  • 유니티 에디터는 C#으로 작성되어 있습니다. (에디터에서 리플렉션을 자동으로 지원해주는것도 이때문일듯...)
  • 유니티를 사랑합니다.. (응?)



참조:


반응형
,
Posted by 알 수 없는 사용자

01. what
02. how
03. storytelling
04. prototyping 上
05. prototyping 下


게임 UX 기획에서 하고자 했던 이야기는 "만들고자 하는 게임의 기술/기능/규칙 같은 어떻게 만들까에 대한 고민보다, 플레이어가 이 게임을 할 때 어떤 감성적인 재미와 만족을 느끼게 될까"로 개발이 시작되었으면 좋겠다는 것이었다.
근래 출시된 액션 혹은 RPG를 위시한 게임들이 전투/협력/수집/성장 같은 기능적, 규칙적 요소들이 대부분 비슷비슷하게 구현되어 있어 크게 차별화되지 못하는 문제가 아쉬웠던 것도 하나의 이유다. 하늘 아래 완전히 새로운 것이 없다고 가정하더라도, 시스템이 유사성을 갖더라도 내러티브나 전달 방법에 있어 차이가 있다면 분명 다른 감성적 경험을 전달할 수 있지 않을까?

개발 단계에서 프로토타입이라는 의미가 '특정 기능이 구현된 플레이 버전' 같은 식으로 좀 애매하게 쓰이는 경우도 많지만, 그보다 '이 게임 만의 특징적 요소를 검증해보기 위한 버전'으로 사용한다면 그 감성적 경험이 과연 재미있을지를 판단하는 기준으로 쓸 수도 있을 것이다. 이 방법이라면, 앞의 'prototyping - 上'편에서 다뤘던 내용처럼 기능을 하나씩 완성해 가는 것이 아니라 필요한 시연 데모 혹은 영상을 만드는 것 만으로도 그 가치를 발휘할 수 있을 것이다.


여튼 이렇게 3월 초에 上편을 작성한 후, 목표로 하고 있던 사전영상화라는 과정을 회사에서 최소 규모 인력으로 진행 중인 현재 프로젝트에 전격(!!) 도입해 개발을 진행하고 있지만, 역시 이번에도 시행착오가 발생함과 동시에 인력 이탈 문제가 발생하여 멘탈이 붕괴... 업데이트가 늦어지게 되었다.


본 연재에서는 게임 플레이 속 유저 경험을 실제 구현 이전에 사전에 예상해 볼 수 있도록 영상으로 프로토타이핑하는 것에 대해 이야기를 하고 있었는데 실제로 이렇게 작업을 진행해 중간 평가를 해본 결과, "이거 그냥 컷씬하고 뭐가 달라?"라는 가슴 아픈 피드백을 받게 되었다. 영상에 UI까지 임시로 얹어보니 그런 느낌이 조금 덜해지기는 했지만 알 수 없는 이 미묘한 이질감...

그렇다!! 실제 게임은 분명 "이미 어느 정도의 가용 범위가 정해진 카메라 시점과 조작에 따라 (조금은 딱딱하게 연결되어가며) 움직이는 모션"이 바탕이 되는데 영상에서는 그러한 제약을 고려하지 않고 일단 내키는대로 작업하게 된 것이 아무래도 "연출된 씬"이라는 느낌을 주게 되어 제대로 된 피드백을 받을 수 없었던 것이다.


게임의 장르가 정해지고 나면 분명 그에 맞는 카메라 시점이 있을 것이다. 근래의 MMORPG나 액션 게임들은 대부분 3인칭으로 캐릭터의 뒤를 쫓아가며 전신을 보여주는 시점 혹은 상체 뒷면을 보여주는 TPS형 시점을 사용하는 경우가 많지만, 디아블로3나 리니지 이터널처럼 애초 의도에 따라 쿼터뷰(isometric)로 고정해 보여주는 경우도 있다.


사전영상화 작업은 플레이어에 의해 조작될 실제 게임 플레이를 가상화 해보는 의도가 있기 때문에, 이 게임의 시점을 고려해 작업하는 것이 중요하다. 장르적 특성을 아우를 수 있는 시점 내에서 카메라가 캐릭터를 쫓아가며 행동을 관찰하도록 의도해야 좀더 실제 게임적인 사전 예측이 가능하게 된다. 물론 이벤트 성격이라든지, 스킬이라든지, 피니시 무브 같은 연출성 플레이의 경우에 별도의 카메라를 사용할 수도 있겠지만 이는 예외적인 경우라, 처음부터 고려할 대상은 아닐 것이다.


애니메이션의 경우도 마찬가지인데, 달려가다가 문 앞에서 멈춰서지 않고 갑자기 사이드스텝 밟고 문을 벌컥 열고 들어가는 등의 모션은 실제 게임 플레이하고는 매우 괴리감이 느껴지는 표현일 것이다. 물론 naturalmotion의 Euphoria 같은 미들웨어를 쓴다면 굉장히 부드럽고 자연스럽게 연결되는 것도 가능하겠지만 그 조차도 조작과 상황에 의해 움직인다는 것을 가정할 때, 문을 연다/ 무엇인가를 설치한다/ 잡아 당긴다 같은 행동을 함에 있어 그 직전 단계에서 UI에 의한 알림을 노출하기 위한 여백 시간도 고려할 필요가 있다.


아래의 영상을 먼저 살펴보자.




이미 액션 어드벤처쪽에서는 독보적인 자리를 차지한 언차티드의 pre-vis 영상이다. 카메라 시점과 캐릭터의 행동이 어떤 식으로 전개될 것인지, 그 의도와 조작계를 감안해 영상으로 보여지게 함으로써 해당 시스템에 대한 감을 잡기가 쉽다.

창발적으로 사용될 수 있는 특징적 기능이 어떤 식으로 게임 내에서 사용될 수 있는지도 미리 설정해 볼 수 있다. 아래는 "포스"를 게임 내에서 어떻게 사용할 수 있고, 그에 대한 반응이 어떻게 전개될지를 알 수 있게 작업된 스타워즈:포스언리쉬드의 pre-vis 영상이다.



사실 사전영상을 만들때는 꼭 자체 리소스를 통해 제작할 필요는 없다. 더미 리소스라든지, 기존의 게임에 사용하던 리소스를 가지고 화이트박스 형태로 쌓아올림으로써 좀더 빠르게 콘티를 잡아보고 반복 수정을 통해 최종 방향을 찾아가는 것이 좋을 것이다.


사전영상화라는 것이 반드시 avi나 wmv 같은 영상의 포맷을 가질 필요는 없다. 더미 레벨을 만들어 본다든지, 더미 콘티를 통해 컷씬의 기본적인 흐름을 볼 수 있게 만드는 것도 사전영상화 작업 중의 하나라 볼 수 있다.



이 영상은 이미 구현된 무브먼트 관련 기능들을 바탕으로 하여, 화이트박스로 레벨을 구성함으로써 어떤 흐름 구성을 갖게 될지를 미리 시뮬레이션 해본 화면을 녹화한 장면이다.



위의 영상은 언차티드 개발사인 너티독의 신작, "The Last of Us"의 2011년 트레일러 영상의 화이트박스 콘티이다. 게임 플레이는 아니고 컷씬의 형태로 작업된 것이겠지만 콘티 조차도 사전영상화 작업을 통해 진행되었음을 알 수 있는 영상이다. 최종 완성본과의 비교는 여기를 눌러 함께 볼 수 있다.


만약 하나하나의 기능이 아닌, 프로젝트 전체 성격을 아우를 수 있는 어떤 특징적 요소의 비전을 영상화 하는 것이라면, 룩앤필이라든지 레벨구성까지 포괄할 수 있는 형태로 언리얼의 마티니 같은 씬 에디터를 통해 실제 게임의 최종적인 모습을 아래처럼 미리 영상화 해 볼 수도 있을 것이다.




사전영상화 작업이 만약 위의 영상처럼 비전 컨셉을 포함해 작업되어, 김학규 PD님이 트위터에 남겼던 것처럼 "이 게임 특징이 뭔가요?"라는 물음 이전에 완성된 영상만으로도 "그래서 이 게임 언제 나와요?"라는 피드백을 받았을 때 어느정도는 성공한 것이라 볼 수도 있을 것이다.


이렇듯, 사전영상화는 비전을 제시하는 포괄적인 형태부터 레벨 구성, 하나의 기능에 대한 활용성 등의 프로토타입 전후 작업 뿐만 아니라 어떤 기능에 대해 누구나 쉽게 이해하고 같은 밑그림으로써 작업할 수 있게 하는 공유의 성격까지 가진 작업 방식의 하나이다. 우리가 아직 출시되지 않은 게임의 동영상이나 스크린샷을 보고 '재밌을 것 같다'는 생각을 하는 것처럼, 실제 구현되지 않았더라도 그 영상을 보는 것만으로 의도가 무엇인지, 어떤 경험이 주어질지를 가늠해 볼 수 있게 한다.




프리-프로덕션은 어떤 것을 만들까에 대한 고민의 비중이 좀더 큰 기간이다. 비전을 세우고 룩앤필과 유저경험의 프로토타입을 만들어나가 분명한 지향점이 정해지고 난 후에는 이제 프로덕션에 돌입해 그에 맞는 시스템이나 컨텐츠를 대량으로 만들어 실제 그 프로덕트를 구성해 나간다.

이 프리-프로덕션의 과정에서 실제로 돌아가는 플레이어블 버전이 있다면 분명 큰 도움이 될 것이다. 어떻게 보면 장르나 비전 목표에 따라서 필수적일 수도 있다. 하지만 어떻게 해야 더 좋은 결과물로 연결될 수 있을까에 대해 그 프로젝트의 많은 부분이 다양하게 시도되고 변형되어가며 달라질 수 있는 시기임을 생각한다면, 이 플레이어블 버전이 반드시 최종 버전까지 고려해 공들여 잘 짜여진 프레임워크와 규약들을 구축해 시작할 필요는 없을 것이다. (물론 대규모 팀이라면, 이러한 작업까지 모두 병행하며 쌓아갈 수 있는 여력이 충분할지도 모른다.)

만약 플레이어블 버전을 만들 수 없는 인력 구성의 소규모 팀 혹은 제안을 위한 프로젝트 TFT(Task Force Team)라면, 비전은 정해졌지만 여러가지 시도를 통해 좋은 쪽을 찾기 위해 내부에 나뉜 애자일 TFT라면 어떻게 프로토타이핑을 해야 할까.

앞서 다뤘던 Low Level 기반이냐 High Level 기반이냐에 관계없이, 게임의 초기 프로토타입의 목적은 '어떻게 동작하고 반응하며 그 플레이가 재미있어 보이는가?'가 가장 중요할 것이다. 이래서 재미있다!!라고 기획서나 PT 문서로써 제시할 수도 있겠지만, 과연 그를 통해 각자가 떠올리는 모습이 모두 공통되게 감성적인 재미를 자극할 수 있을지는 불분명하다.


제작을 함에 있어 무엇인가를 만들어야 할 때, 말로써 설명하거나 그림이나 도표로써 설명할 수도 있겠지만 모두가 같은 이해를 할 수 있도록 영상으로써 적절한 시기에 제시될 수 있다면 좀더 빠르고 효율적인 반복 개발에 도움을 줄 수 있을 것이다.


무작정 참고할 타이틀을 하나 잡고 비슷하게 만든다 혹은 이미 표준화되다시피 한 기획 구성과 방법론으로 만든다 같은 개발 진행보다, 유저 경험을 어떻게 차별화 할 것인가의 관점에서 개발을 시작해 다양한 결과물로 귀결될 수 있는 방법들을 통해 더 재미있고 좋은 게임들이 많이 등장할 수 있기를 기대해 본다.




반응형

'기획' 카테고리의 다른 글

1 depth, 1 play, 1 rank  (2) 2012.12.11
게임개발에서의 스토리와 내러티브  (1) 2012.07.23
게임 스토리와 연출  (8) 2012.06.10
FDB 작성 및 적용 사례 - Config  (8) 2012.04.20
공간 최적화로 레벨 디자인하기  (8) 2012.04.17
,
Posted by 알 수 없는 사용자
 

안녕하십니까 여러분.

 

이번에 새롭게 연재를 시작하게 이세훈 이라고 합니다. 반갑습니다.

 

저를 아시는 분이 거의 없을 하니, 소개를 간단히 올려 드리지요.

 

이세훈

현재 : Kuno Interactive Art Director

과거 : Rare / Microsoft Games Studio technical art lead

가장 최근 상용화된 프로잭트 : Kinect Sports 2

정도 입니다…(혹시 알고 싶으시면 연락 주세요 :p )

 

Rare 있었을 때는 게임도 만들었지만 그 외에도 360 플랫폼 개발이나 여러 가지 MS 필요로 한 프로젝트에도 참여한 콘솔 토박이… 입니다. 어려서 한국을 떠나 들어 온지는 일년이 안돼 가고요 아직 적응 입니다. (한글도 씁니다). 그렇니 여러분들.. 글을 읽다가 웃으셔도 무방 합니다,, ^^

 

여기 계신 분들이 워낙 대단하신 분들이 많기에 제가 얼마나 보탬이 될 수 있는지는 모르겠지만 일단은 시작은 해보려고요.. 한국말로 블로그 쓰는 게 정말 힘들겠지만 이것도 배운다는 도전 정신으로 하겠습니다.

 

처음 부터 무슨 얘기를 할까 고민을 많이 했습니다 , 거창한 얘기를 시리즈로 시작 하기 보다는 처음 이니까 앞으로 회는 가벼운 마음 으로 짧게 유용한 프로그램들을 조금 소개해 드리는 걸로 시작해 보려고 합니다.

 

Hotkey Master

 

처음 소개할 프로그램은 Hotkey Master 입니다. 이건 , 그대로 사용자가 지정한 hotkey 프로그램에 연결해 준다거나 해서 실행시키거나 할 수 있는 프로그램인데요. 이런 프로그램을 벌써 쓰고 계신 분들도 많으시겠지만 보신 분들은 한번 시도해 보시는 것도 괜찮지 않을까요 . 써보면 일단 처음에 셋팅 하는 조금 귀찮긴 하지만 다음 부터는 조금 편해지는 것이, 요놈 때문에 하루에 5 분만 절약할 수 있어도 일년이면 30시간 (하루 정도) 버는 인데요, 수학적으로 말씀 드리면 그렇다는 거고 일단은 귀찮은 게 줄잖아요…

 

제가 프로그램을 사용학 결정적인 이유도 저의 게으름 때문 이었습니다.

 

저희 쿠노 에서는 SVN 으로 관리를 하고 있는데요. SVN 써보신 분들은 아시겠지만 이놈이 가끔가다 탐색기에서 파일에 뜨는 상태 알림 아이콘이 제대로 나오는 경우가 많습니다. 이런 경우 저는 F5 무지막지 하게 눌러 대면서 SVN 빨리 아이콘을 보여줄 때까지 기다리거나 아니면 task manager 띄워 놓고 TSVNCache.exe 강제 종료 시킵니다.

TSVNCache.exe 강제로 종료시키고 F5 눌러 리프레쉬 시키면 잘나오거든요.

 

(으.... 아트스티들은 SVN 이 싫다~ 우리에게 SVN 을 강요하지 말라...)

 

근데 이게 무지 귀찮은 겁니다! (~ 상당히 게으른 거.. 아는데요.. 저도 게으름이 이런 쪽에서는 발전을 이룰 수 있는 모티브가 된다고 믿고 있어서요..) 그래서 hotkey master crtl-F5 TSVNCache.exe 강제로 종료 시키도록 설정을 해놨습니다. 그 다음 부터는 저는 F5 마르고 닳도록 누르지 않아도 되었고요. 당연히 다른 쪽에서도 십분 활용 하고 있습니다. Technical Art 쪽에서 일을 하다 보면 데스크탑 있는 아이콘을 찾아서 누르기가 쉽지 않은 (귀찮은) 때가 상당히 많은데요 (하도 많이 열어 놓고 겹치고 해서) 요놈으로 어느 정도는 해결을 봤습니다. 심지어는 코딩 할 때 자주 쓰는 용어를 자동화 할 수도 있습니다… ( Debug.Log("") <- 이런 라든지 ^ ^ ).

 

이런 프로그램이 상당히 많기는 한데요, 제가 hotkey master 추천 드리고 싶은 이유는 용량은 작으면서도 셋팅 하기도 쉽고 일은 한다는데 있습니다. (이 정도면 훌륭한 거 아닌가요) 여러분들도 만약 이런 hotkey 사용을 하시지 않으시면 한번 보세요… 혹시 내가 이전에는 이렇게 작업을 했나 편리함에 빠지실 수도 있습니다.

 

끝으로 hotkey master 받으실 수 있는 링크하고 기본적으로 셋팅 하는 방법을 알려드리고 마칠까 합니다.

 

http://www.hotkeymaster.com/

 

다음 에는 Download 에 가셔서 받으시고요…

 

설치 하신 에는 아이콘 트레이 hotkey master 아이콘이 뜰 겁니다. 그걸 클릭 하시면 다음과 같은 창이 뜨는데요.

 

 

 

거기서 보이시는 것과 같이 new 하시고, 설정 하시고 싶으신 일을 골라 적용해 주시면 입니다~

.. 뭐야.. 끝이잖아.

 

끝이네…

 

~ 가격은 30 평가 있고 있고 쓰려면 5달러 내야 한다는데 개인적으로는 5달러의 가치는 있다고 생각하고요.  혹시 같은 종류의 공짜인 프로그램을 아시는 분들은 댓글 추천 부탁 드립니다. 참고로 저는 hotkey master 사장하고 아주 가까운 사이…. 아닙니다.

 

, 정도의 정보는 여기 계신 분들께는 별로 도움이 되지는 않을 같지만 혹시나 해서 hotkey 써보신 경험이 없으신 구독자들 분께 조금이나마 도움이 될까 해서 올려 봤습니다. 이런 종류의 작고 유용한 프로그램들은 활용만 잘하면 편리한 것들이 많은 같습니다.

 

그럼 다음에 뵙죠~

반응형
,