Tip:
Highlight text to annotate it
X
재밌는 UDK 튜토리얼을 다시 찾아 주셨군요! 스케일폼의 매튜 도일, 다시 인사 드립니다.
UDK 에서 GFx HUD 마스터하기 관련 세 번째 튜토리얼입니다.
2010년 9월 UDK 빌드에 있는 메인 HUD 클래스 GFxMinimapHud.uc 를 살펴 보도록 하겠습니다.
예전 튜토리얼부터 계속 보아오셨다면, 이 클래스가 모든 HUD 마법이 벌어지는 곳이라는 것을 아실 것입니다.
마찬가지로, 다룰 것이 매우 많습니다.
그래서 모든 그래픽 HUD 엘리먼트를 설명하기 보다는, 중요한 요소 몇 개만 살펴 보도록 하겠습니다.
그에 대해 미리 알아둬야 나머지 것들도 이해할 수 있을 테니, 시작해 보도록 하죠.
udk_hud.fla 가 열려있지 않으면 여십시오.
역시 즐겨 쓰는 에디터로 GFxMinimapHud.uc 를 엽니다.
기억나시나요? GFxMinimapHud 가 실제로 GFxMoviePlayer 를 확장하는 클래스입니다.
간단히 말하면, 이 클래스는 Flash 파일 내 모든 HUD 무비 클립과 텍스트 필드로의 참조를 캐시합니다.
그런 다음 필요에 따라 엘리먼트를 업데이트합니다.
이 클래스에는 상당수의 전역 변수가 있습니다.
먼저 미니맵에 관련된 것이 몇 개 있습니다.
다음으로 MessageRow 데이터 구조와 로그 메시지에 관련된 변수가 여럿 있습니다.
그리고서 엄청난 양의 GFxObjects 가 남습니다.
이들은 udk_hud.swf 안에 있는 Flash 엘리먼트로의 참조입니다.
이를 좇아 보면, 지난 번 알려진 양을 저장하는 데 사용되는 변수가 몇 있습니다.
체력, 갑옷, 잔탄수 등 말입니다.
HUD 엘리먼트를 업데이트시켜야할지 말아야할지 알기 위해 중요한 정보입니다.
일단은 첫 함수로 건너가 봅시다. registerMinimapView 죠.
다음 비디오에서 미니맵을 설명하겠습니다.
지금은 그냥 미니맵이 로드될 때 Flash 에서 이 함수가 호출된다고 이해하고 계십시오.
다음 두 함수는 HUD 에 로그를 표시하는 데 필요한 모든 것을 초기화시키는 데 사용됩니다.
첫째는 CreatMessageRow() 입니다.
이 함수는 GFxObject 를 반환하는데, 여기서는 빈 무비 클립입니다.
호출되면 AttachMovie 를 사용하여 GFxObject LogMC 안에 놓이는 빈 무비 클립을 새로 생성하며,
이는 화면상에 표시되는 로그에 사용 가능합니다.
첫 파라미터는 Flash 파일에서 어느 라이브러리 심볼을 첨부시킬지를 지정합니다.
이 경우, LogMessage 심볼의 익스포트 이름입니다.
둘째 파라미터는 새 심볼 이름을 지정하는 것입니다. (logMessage1, logMessage2 등)
다음은 InitMessageRow 입니다.
이 함수는 새 message row 를 초기화하기 위해 위에 선언된 MessageRow 데이터 구조를 사용합니다.
이는 잠시 후에 확인하게 될 다음 함수 Init 에서 호출됩니다.
105 번 줄에, 예전 함수 CreateMessageRow 를 호출하고,
mrow.MC 내 첨부된 LogMessage MovieClip 으로의 참조를 저장합니다.
GetObject 를 사용하여, 그 텍스트를 설정할 수 있도록 그 message row movie clip 내 textField 로의 참조를 캐시할 수 있습니다.
Flash 오브젝트 구조를 검사해 봅시다.
라이브러리 패널에서, 로그 애셋 폴더를 열고 logMessage 무비 클립을 더블클릭하여 엽니다.
스테이지 상의 오브젝트에 클릭하여, 메시지의 인스턴스 이름을 갖고 있음을 확인할 수 있습니다.
무비 클립으로 파고 내려가 보면, textField 의 인스턴스 이름을 갖고 있는 실제 텍스트 필드를 찾을 수 있습니다.
이제 HUD 클래스 파일로 되돌아가 보면, 107 번 줄이 와닿기 시작할 것입니다.
텍스트필드에 html 스타일 텍스트 태그를 허용하려 하기에, mrow.TF 의 html 속성을 true로 설정하기 위해 SetBool 을 사용합니다.
html 텍스트필드는 현재 빈 텍스트로 설정하기 위해 SetString 를 사용합니다.
마지막으로 사용가능한 message rows 의 pool 인 FreeMessages 배열에 새 message row 를 추가합니다.
새로이 생성되고 환경설정된 GFxObject mrow.MC 를 반환하기 전에 말입니다.
그러면 Init 함수가 나옵니다.
기억나세요? 이 함수는 HUD를 처음 인스턴스화할 때 UTGFxHudWrapper.uc 에 의해 호출되는 함수입니다.
주요 임무는 모든 플래시 무비와 텍스트 필드로의 참조를 캐시하는 것이고요.
첫 로컬 변수는 약간 아래의 for 루프에 사용되됩니다.
다음 변수는 폐기되었으니 무시해도 됩니다.
다음, super 클래스 또는 GFxMoviePlayer, Init 함수를 호출합니다.
이는 일반적은 객체 지향형 프로그래밍 사용법입니다.
GFxMoviePlayer 의 Init() 함수 안에는 실행해야 하는 로직이 있을 수 있습니다.
함수를 덮어쓰기에, super 클래스의 버전을 호출하거나, 그 코드를 여기에 복사해 붙여넣거나 해야 합니다.
나중에 쉽게 접근할 수 있도록 world info 를 저장하며, game replication info 도 구해올 필요가 있습니다.
또한 모든 게임 데이터를 구해 GRI 내에 저장하기도 합니다.
다음 무비를 시작하여 재생시키는 GFx 함수가 둘 옵니다. 각각 Start 와 Advance 입니다.
다음 작은 블록 세트는 여러가지 중요 변수에 대한 초기 값을 설정합니다.
로그 메시지의 수는 물론 지난 체력, 갑옷, 탄창 등도요.
새 게임을 시작하려 하니 이 값은 음수값으로 설정합니다.
다음은 if 문 블록으로, 위의 폐기된 임시 GFxObject 를 활용하는 것입니다.
그러므로 이 if 문 전부를 완전히 무시해도 됩니다.
그래도 일단 설명해 보자면, 얘들의 역할을 말씀드리겠습니다.
본질적으로 얘들은 게임이 시작될 때 보이게 하고 싶지 않은 무비 클립을 숨기는 데 사용됐었습니다.
GetVariableObject 를 사용하여 임시 위젯 안에 Flash 파일로부터의 무비 클립을 저장합니다.
그런 다음 우리 GetVariableObject() 가 적절한 참조를 반환했는지 검사해 봅니다.
그렇다면 SetBool 을 사용하여 그 오브젝트의 visibility 를 false 로 설정합니다.
그렇지 않다면 MovieClip 은 존재하지 않는 것이고, 숨길 필요가 없는 것입니다.
그래도 이 무비 클립은 현재 HUD Flash 파일에 있지 않습니다.
계속해서, Flash 의 시간선 루트에서 로그 무비 클립으로의 참조를 캐시합니다.
Flash 에서 로그 레이어를 보면, 로그 인스턴스 이름을 가진 빈 무비 클립을 갖고 있음이 보입니다.
그리고서 위의 InitMessageRow 함수를 실행하는 for 루프를 실행합니다.
메시지 로그에 대한 빈 html 텍스트 필드가 담긴 새 무비 클립을 15개 만들어 줬죠.
그런 다음 Flash 파일의 다양한 무비 클립과 텍스트 필드 전부로의 참조를 캐시합니다.
접근이나 변경할 때마다 구해오지 않기 위해 이 항목으로의 참조는 한 번 캐시하려 합니다.
약간의 성능 페널티를 없애기 위함입니다.
예로써 헬쓰 텍스트 필드와 무비 클립을 들여다 봅시다.
GetVariableObject 를 사용하여 HealthTF 내의 _root.playerStats.healthN 을 캐시합니다.
HealthBarMC 는 _root.playerStats.health 를 담습니다.
이제 Flash 파일 속으로 가 봅시다.
계층구조의 루트 _root 에서 시작합니다.
우하단 무비 클립을 클릭하면, playerStats 의 인스턴스 이름이 있는 것을 볼 수 있을 것입니다.
이는 _root.playerStats 를 줍니다. 그걸 더블클릭해서 playerStats 속으로 들어갑니다.
이 무비 클립 안에서, healthN 레이어를 잠금해제하고, 스테이지 위의 텍스트 필드에 클릭합니다.
healthN 인스턴스명을 갖는 것을 볼 수 있으며, _root.playerStats.healthN 계층구조를 내 줍니다.
UnrealScript 로 캐시했던 것처럼 말입니다.
health 레이어를 풀고, health bar 그래픽에 클릭합니다.
health 인스턴스명을 갖고 있으며, _root.playerStats.health 계층구조를 내 줍니다.
자 다시 UnrealScript 로 돌아와서.
여기에 팀 기반 무비 클립을 캐시하는 블록이 있습니다.
주의할 점은, 게임이 팀 게임이 아니라면,
그 오브젝트의 SetVisible 속성으로 이 무비 클립 중 여럿을 숨기도록 설정한다는 것입니다.
다양한 방향성 피격 표지 무비 클립은 HitLocMC 배열의 엘리먼트로써 저장되며,
맨 위 표지부터 시작해서 시계방향으로 이동합니다.
이 참조 전부를 캐시한 다음에는, 그들 중 다수에 약간의 3D 변형 작업을 합니다.
ActionScript 2 는 플로트와 인티저를 구분하지 않습니다.
그래서 SetFloat 를 사용하여 _yrotation 값을 3D 공간의 Y 축으로 약간 회전시켜 각 무비 클립으로 전송합니다.
마지막으로, Init 함수는 true 파라미터를 가진 ClearStats 를 호출합니다.
다음 함수로 건너가 봅시다.
이는 ClearStats 를 설명하기 위해 시간을 시, 분, 초 포맷으로 맞춥니다.
ClearStats 의 역할은 단지 다양한 HUD 무비 클립과 텍스트 필드를 "새 게임" 상태로 설정하는 것입니다.
처음 세 줄은 ASDisplayInfo 인스턴스를 만드는 것인데,
그래픽 상태 바의 X 크기( 또는 폭)를 설정하는 데 사용되는 것입니다.
그 DI 에게 X Scale 이 있다 해 주고, X Scale 값을 그 최대 크기의 0% 로 설정합니다.
이들 if 문 중 일부를 조금 자세히 살펴 봅시다.
둘째 if 문은 LastHealth 가 현재 초기화된 값 -10 이외의 것인지 검사해 봅니다.
그렇다면 그 텍스트 필드에 대한 캐시된 참조의 텍스트 속성에서 SetString 을 사용하여 health 텍스트 필드를 공백으로 설정합니다.
보셨다시피 녹색 단색 바인 헬쓰 바 무비 클립도 설정했는데,
위 DI에 저장한 display info 속성을 갖게 하기 위함입니다.
이런 식으로 헬쓰 바 그래픽의 폭을 0% 로 설정하여, 숨겨진 것으로 렌더링합니다.
마지막으로 LastHealth 를 -10 으로 설정하여 "새 게임" 상태를 나타냅니다.
LastAmmoCount 에도 비슷한 작업을 해 주는데, 이 경우에는 그래픽 바가 없습니다.
Flash 의 탄약 표지를 빠르게 살펴 봅시다.
탄약 표지는 키프레이밍된 애니메이션을 사용함을 알 수 있는데, 각 키프레임에는 각기 다른 양의 탄약이 표시되고 있습니다.
GFxMinimapHud 로 되돌아와서, 탄약 바 무비 클립에게 프레임 51 에서 GotoandStopI 하라 합니다.
본질적으로는 그래픽이 없는 빈 프레임을 표시하라고 하는 것입니다.
GotoAndStopI 에서 I 는 정수의 Integer 이며, 프레임 번호를 정수로 전달하기 때문입니다.
I 가 없는 GotoandStop 을 사용해도 됩니다. 그런 경우,
Flash 의 프레임 라벨에 해당하는 문자열 값을 전달해 줘야 할 것입니다.
그리고 LastWeapon 을 살펴보니, SetVisible(false) 를 사용하여 무비 클립을 숨길 수도 있음을 알았습니다.
자, 다음 함수로 바로 가 보겠습니다.
간단히 말해, AddMessage 는 로그 메시지를 표시하는 데 사용됩니다.
이 함수는 아래 AddDeathMessage 에서, UTGFxHudWrapper 의 LocalizedMessage 에서도 호출됩니다.
파라미터를 둘 받습니다. 메시지의 종류와 메시지 자체로, 둘 다 문자열입니다.
새 로그 메시지가 생기면 예전 메시지를 화면에서 일정한 정도 밀어 올리도록 하고 싶습니다.
그러려면 ASDisplayInfo 인스턴스를 사용하여
새 메시지 공간을 만들기 위해 로그 메시지가 이미 표시되어 있는 곳의 x-y 좌표를 변경합니다.
메시지 길이가 없다면, 표시할 것이 없으니 안전히 반환해도 됩니다.
우리 FreeMessages 풀에 현재 사용가능한 미사용 로그 메시지가 있는 경우,
새 메시지를 만들기보다는 그냥 그것을 사용하면 됩니다.
그러려면 그냥 FreeMessages 목록 끝에서 하나를 pop 해낸 다음 그걸로 가면 됩니다.
그러나 현재 사용가능한 메시지 열이 없다면, 현재 표시되고 있는 로그 메시지 열 중 가장 오래된 것을 사용할 것입니다.
그리고서 mrow textField 에 표시될 String 을 setString 을 사용하여 설정하고, 메시지의 종류도 설정합니다.
새 로그 메시지의 Y 값은 0 이 될 것입니다.
이 Y-좌표는 부착된 MovieClip 에 상대적인 값이 될 것입니다.
이 경우, 새 메시지는 로그 무비 클립 콘테이너의 하단에 표시될 것입니다.
로그 메시지 무비 클립에게 "show" 로 가서 재생하라 고 해 주어, 실제로 표시하게 합니다.
Flash 파일을 되돌아 보니,
로그 메시지가 show 프레임에서 시작하여 몇 초간 있다 페이드 아웃되어, 제대로 표시되고 있음을 볼 수 있습니다.
그 후 for 루프를 사용하여 각 로그 메시지의 Y 값을 설정해 줍니다.
예전 로그 메시지 전부를 MessageHeight 에 지정된 양 만큼 올리기 위해서입니다.
각 SetDisplayInfo() 호출에 대해 동일한 ASDisplayInfo 인스턴스를 재사용할 수 있는데,
각 호출마다 ASDisplayInfo 를 새로 만들기 보다는 그 Y 속성 값을 변경해 주기만 하면 됩니다.
MessageHeight 값은 default properties 에서 찾을 수 있으며, 38 픽셀로 설정되어 있습니다.
마지막으로 현재 표시되고 있는 로그 메시지 풀에 새 로그 메지시 열을 삽입합니다.
자, 이번 비디오는 여기까지입니다.
다음 비디오에는 UpdateGameHud() 부터 찍어야 겠군요.
다음에 이어서, GFxMinimap HUD 를 마무리하도록 하겠습니다.
그때까지 안녕히, 스케일폼의 매튜 도일이었습니다.
한글 자막: 홍성진@에픽 게임스 코리아 관련 문의: sungjin.hong@epicgameskorea.com