UDN
Search public documentation:

UnrealScriptGameFlowKR
English Translation
日本語訳
中国翻译

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 홈 > 언리얼스크립트 > 언리얼스크립트 게임 흐름
UE3 홈 > 게임플레이 프로그래밍 > 언리얼스크립트 게임 흐름

언리얼스크립트 게임 흐름


문서 변경내역: Jeff Wilson 작성. 홍성진 번역.

개요


언리얼 엔진 3의 게임 흐름은 다른 분야 또는 단순히 언리얼 엔진 3 방식에 익숙치 않은 프로그래머에게 생소할 수 있습니다. 이 문서의 목적은 게임 내 흐름의 대강을 훑어 보고, 그 흐름을 원활히 하는 데, 즉 게임을 요구에 맞게 특화시키는 데 사용되는 중요 함수들을 짚어 보는 것입니다.

일반적인 이벤트 흐름은:

+ 엔진 초기화(initialize)
|--+ 엔진이 맵을 로드
   |--- 게임타입 설정
   |--+ 게임플레이 초기화
   |  |--- GameInfo:InitGame() 호출, 게임타입 초기화
   |  |--- Actor::PreBeginPlay() 호출, 모든 액터 초기화
   |  |--- Actor::PostBeginPlay() 호출, 모든 액터 초기화
   |--+ 플레이어 참가
      |--- GameInfo::Login() 게임타입에서 호출, 플레이어 스폰 처리
      |--- GameInfo::PostLogin() 게임타입에서 호출, 새 플레이어 처리

gameflow.jpg

스타트업 무비


엔진 시동시 스타트업 무비 시리즈가 표시됩니다. 여기에는 "Powered by Unreal" 무비, "Epic Games" 무비 등이 포함되며, 다른 무비도 추가할 수 있습니다. 스타트업 무비는 DefaultEngine.ini 파일 안 [FullScreenMovie] 섹션의 StartupMovies 배열에 지정된 풀스크린 비디오 (.bik) 입니다.

[FullScreenMovie]
+StartupMovies=UDKFrontEnd.udk_loading

맵 로드


언리얼 엔진 3 의 모든 게임플레이와 인터랙션은 맵 안에서 벌어집니다. 엔진 시동시 항상 맵을 로드합니다. 맵 로딩 프로세스는 맵 열기 뿐만 아니라 새로운 게임타입을 로드하고 초기화시킨 다음 매치를 시작하는 등 일련의 이벤트를 시작시키기도 합니다.

엔트리 맵

게임 시작시 로드할 맵은 명령줄에 지정할 수도 있고, 지정된 맵이 없으면 디폴트 맵이 로드됩니다. 일반적으로 맵을 지정하지 않아 디폴트 맵이나 엔트리 맵을 로드하게 됩니다.

디폴트 맵은 DefaultEngine.ini 파일의 [URL] 섹션에 지정되어 있습니다.

[URL]
Map=UDKFrontEndMap.udk

이는 보통 플레이어 스타트를 가진 매우 단순한 맵으로, 게임플레이를 호스트용은 아닌 게임의 메인 메뉴 로드용입니다. 전체 UDKFrontEndMap.udk 맵은 아래와 같습니다:

entrymap.jpg

메인 메뉴

메인 메뉴에 특정 메뉴를 사용하도록 한다던가 메인 메뉴에 게임 스타트업을 집어넣는다던가 하는 것을 게임에 강제하는 함수성은 따로 없습니다. 위에서 간단히 얘기했던 것처럼, 스타트업시 로드되어 메인 메뉴를 로드하는 것은 맵이 할 일입니다.

이를 통해 게임 시동 방식에 엄청난 유연성과 제어력을 확보할 수 있습니다. 예를 들어 어떤 게임에서는 시작하자마자 바로 메인 메뉴를 들이밀 수도 있고, 다른 게임에서는 동영상을 먼저 보여줬다가 메인 메뉴로 전환되게 할 수도 있으며, 또 다른 게임에서는 게임플레이를 약간 선보이다가 메뉴를 표시할 수도 있습니다. 필요에 따라 메인 메뉴를 동째로 생략해 버릴 수도 있습니다.

메뉴는 키즈멧을 사용하여 엽니다. UDKFrontEndMap.udk 맵에서 메인 메뉴를 로드하는 키즈멧 예제는 다음과 같습니다:

mainmenu_kismet.jpg

로딩 화면

한 맵에서 다른 맵으로 전환되면 로딩 화면이 표시됩니다. 로딩 화면은 실제로 DefaultEngine.ini 파일 내 [FullScreenMovie] 섹션의 LoadMapMovies 배열에 지정된 것 중 임의로 선택된 풀스크린 비디오 (.bik) 입니다.

[FullScreenMovie]
+LoadMapMovies=UDKFrontEnd.udk_loading

게임 스타트업


언리얼에서 "게임" 이란 용어는 여러가지 의미를 지닙니다. 여기서 게임은 새 맵을 로드한 이후 벌어지는 게임플레이와 이벤트를 말합니다.

게임 초기화

현재 GameInfoInitGame() 이벤트는 모든 Actor 의 PreBeginplay() 이벤트를 포함한 다른 스크립트가 실행되기 전에 호출됩니다. 이는 주로 게임타입이 자체 파라미터를 셋업하고 필요한 헬퍼 클래스를 스폰하도록 하기 위함입니다.

event InitGame( string Options, out string ErrorMessage )

플레이 시작 전

PreBeginPlay() 이벤트는 Actor 의 스크립트 실행이 시작된 이후 Actor 에서 처음 호출되는 스크립트 함수입니다. 이름에서 게임플레이 시작 전, 즉 게임 시동시 Actor 가 존재하는 경우 호출됨을 알 수 있습니다. Actor 가 플레이 도중 스폰되는 경우, 게임플레이가 이미 시작되었더라도 이 이벤트는 호출됩니다. 여기서 매우 전문화된 초기화를 할 수는 있지만, 이 시점에서 Actor 의 컴포넌트가 초기화된 것은 아니며, 외부 오브젝트가 초기화되었는지를 확실히 확인할 수 있는 방법도 없다는 점 참고하시기 바랍니다.

event PreBeginPlay()

플레이 시작 후

PostBeginPlay() 이벤트는 다른 모든 Actor 가 그 PreBeginPlay() 이벤트를 통해 초기화된 이후 호출됩니다. 이 이벤트는 보통 프로퍼티 초기화, 월드의 다른 액터로의 리퍼런스를 찾기, 다른 일반적인 초기화 수행 등에 사용됩니다. 이 이벤트는 Actor 에 대한 컨스트럭터의 스크립트 버전이라 생각해도 좋습니다. 그렇다 해도 Actor 를 초기화하려면 거기서 쓸 수 있는 전문화된 이벤트를 몇 가지 사용해 줘야 합니다. 예를 들어 애니메이션이나 애님트리와 관계있는 초기화의 경우 PostInitAnimTree() 이벤트에서 해 주는 것이 최적일 텐데, 바로 그 것이 애님트리가 생성되고 초기화된 이후 호출되는 것이기 때문입니다. 이러한 종류의 전문화된 초기화 수행용으로 제공되어 있는 이벤트는 많이 있습니다. PostBeginPlay() 이벤트에 전용 초기화 함수성을 추가하기 전 그러한 것을 먼저 검색해 보는 것이 가장 좋습니다.

event PostBeginPlay()

플레이어 생성

플레이어 생성은 로그인 프로세스를 통해 게임타입 안(즉 GameInfo 클래스)에서 처리됩니다. 네트워크 온라인 멀티플레이어 게임 맥락에서 생각해 보면 이러한 개념이 완벽히 이해될 것입니다. 물론 온라인 상황에서 몇 가지 추가로 해 줘야 하는 것이 있기는 하지만, 언리얼에서는 게임이 온라인이든 오프라인이든, 멀티플레이어든 싱글플레이어든 상관 없이 똑같은 기본 프로세스를 활용합니다.

로그인 프로세스는 여러 단계로 나뉘어 있습니다:

  • PreLogin
  • Login
  • PostLogin

PreLogin() 이벤트는 네이티브 코드에서 호출되며, 플레이어가 게임에 참가할 수 있는지를 결정하는 역할을 담당합니다. 게임타입의 AccessControl 오브젝트를 사용하여 플레이어가 참가할 수 있는지를, 그 PreLogin() 함수를 호출하여 판단합니다.

event PreLogin(string Options, string Address, out string ErrorMessage)

Login() 이벤트는 네이티브 코드에서 호출되어 플레이어의 스폰을 담당합니다. 새 플레이어 생성에 필요한 전문화된 함수성은 여기에 추가해야 합니다.

event PlayerController Login(string Portal, string Options, const UniqueNetID UniqueID, out string ErrorMessage)

PostLogin() 이벤트는 플레이어가 게임 참가에 성공한 이후 네이티브 코드에서 호출됩니다. 플레이어 초기화를 하기 좋은 곳이며, PlayerController 상의 리플리케이트된 함수를 호출하기 안전한 곳이기도 합니다.

event PostLogin( PlayerController NewPlayer )

경기 시작

실제로 게임은, 플레이어가 스폰되는 순간부터 게임이 끝날 때까지 벌어지는 게임플레이가 그렇듯이, 경기(match) 라고도 합니다. 이는 단지 용어일 뿐, 언리얼 엔진 3 로 만들 수 있는 게임의 종류에 관계가 있는 것은 아닙니다.

경기는 PostLogin() 이벤트에서(, 또한 PendingMatch 스테이트의 StartMatch()StartArbitratedMatch() 에서도) 호출되는 게임타입의 StartMatch() 함수가 호출될 때 시작됩니다. 이 함수는 플레이어의 Pawn 스폰과 모든 플레이어에게 경기가 시작되었음을 알리는 것을 담당합니다.

function StartMatch()

플레이어 PawnRestartPlayer() 함수에서 실제로 스폰됩니다. 이 함수는 StartHumans()StartBots() 함수에서 호출되며, 그 뒤 StartMatch() 함수에서 호출됩니다. Pawn 스폰 작업에 추가로 이 함수는 플레이어를 시작시킬 지점, 예로 PlayerStart Actor 의 위치를 찾습니다.

function RestartPlayer(Controller NewPlayer)

게임 끝


게임이 끝났는지를 결정하는 것은 게임타입 입니다. 일정한 간격마다 혹은 엔진이 발동시키는 자동 검사로 결정되는 것은 아닙니다. 중요한 이벤트가 발생했는데 그게 게임을 끝낼 사유가 되는지 검사해 볼 수 있도록 게임타입에 알리는 것은, 게임-관련 Actor 의 책임입니다. 그러한 검사는 보통 GameInfo 서브클래스에 추가된 전문 함수에서 이루어집니다. 예를 들어 UTGame 게임타입에는 플레이어가 죽을 때마다 게임 끝인지 판단하는 함수 CheckScore() 가 있습니다. 이 함수 중 하나가 게임을 끝내야 한다 결정을 내리면, 그 함수는 EndGame() 함수를 호출하고, 차례로 CheckEndGame() 을 호출합니다. 이 함수들은 게임을 끝내도 되는지 확인한 다음 현재 게임타입을 끝내는 데 관련된 작업에 착수합니다.

어드벤처 롤플레잉 게임을 예로 들자면, 플레이어가 던전 안에 있고 보스를 물리치거나 임무를 완수한 경우, 보스나 임무가 그 내용을 게임타입에 알리는 것입니다. 그러면 게임타입은 모든 게임 끝 조건에 맞는지를 확인합니다. 게임 끝 조건이 정말로 맞아 떨어지면, 게임타입은 EndGame() 을 호출하여 게임을 끝내는 데 필요한 작업을 취합니다: 플레이어를 메인 월드로 돌려보내고, 던전이 완료되었다고 어떤 식으로든 기록하는 것이지요. 메인 월드에서 게임타입은 플레이어의 진행상황, 이를테면 플레이어가 끝낸 던전 목록같은 것을 로드하여 게임 끝 조건에 맞는지 검사하는 것입니다. 조건이 맞으면 게임타입은 EndGame() 을 호출하여 게임을 끝내는 데 필요한 작업에 착수합니다.

각각의 게임마다 규칙, 흐름, 게임 끝 조건도 각기 다르겠지만, 여기 든 예제로 그 개념만은 확실히 잡을 수 있으리라 봅니다.