UDN
Search public documentation:

ScaleformQuickStartKR
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 홈 > 유저 인터페이스와 HUD > 스케일폼 GFx > 스케일폼 GFx 퀵 스타트

스케일폼 GFx 퀵 스타트


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

개요


스케일폼으로 만든 메뉴나 HUD 를 구성하여 언리얼 엔진 3 에서 처음 돌아가게 만드는 작업은 만만치 않아 보일 수 있습니다. 그러나 그 프로세스는 매우 간단하고 말썽도 없습니다. Adobe Flash Professional(이나 그에 상응하는 것)이 필요하며, 그 사용법도 아셔야 합니다. 플래시에서 모든 엘리먼트를 구성하는 방법까지 깊이 들어가지는 않을 것이기 때문입니다. 이 글의 목적은 스케일폼 UI 가 언리얼 엔진 3 에서 돌아가도록 만드는 데 필요한 요점을 짚어보기 위함이지, 스케일폼이나 플래시 자체에 대한 사용법을 알아보기 위함은 아닙니다.

여기서는 (아래 보이는) 단순한 메뉴를 만드는 과정을 보여줍니다. 이 메뉴를 통해 플레이어가 자신에 대한 프로파일 정보를 약간 입력할 수 있으며, 그것을 바탕으로 환영 인사를 출력합니다. 다시 강조하지만, 이 글의 요점은 그저 잘 돌아가는 스케일폼 UI 를 언리얼로 가져오는 법을 빠르게 보여드리기 위함입니다.

quickstart.jpg

씬 셋업


씬의 셋업 작업은 모두, 쉬운 인터페이스를 사용하여 엘리먼트를 놓고 수정하고 애니메이트시키는 플래시를 통해 이루어집니다. 여기서는 씬의 각 엘리먼트 셋업을 단계별로 들어가 보기 보다는, 씬을 어떻게 조직화시키는지를 개괄해 보겠습니다. (아래 내려받기에) 제공된 플래시 파일을 사용하여 따라해 보시거나, 참고삼아 자신만의 예제를 만들어 보셔도 좋습니다. 일반적인 스케일폼 GFx 관련 작업을 더욱 자세히 설명한 문서, 특히 CLIK 컴포넌트에 대해서는 공식 스케일폼 문서 사이트 를 참고하시기 바랍니다.

예제 파일
UI_QuickStart - 1/4
UI_QuickStart - 2/4
UI_QuickStart - 3/4
UI_QuickStart - 4/4
UI_QuickStart AS3 version (part 1 of 2)
UI_QuickStart AS3 version (part 2 of 2)

씬은 배경 이미지, 메시지를 표시하는 라벨, 데이터를 입력/표시하는 필드 몇, 정보를 저장하거나 메뉴를 닫는 버튼 둘로 이루어져 있습니다.

quickstart_scene.jpg

애니메이션

배경 이미지 외의 각 엘리먼트에는 메뉴가 열릴 때 화면 밖에서 들어오는 애니메이션이 있습니다. 분명 필수적인 것은 아니나, 그저 애니메이션이 어떻게 처리되나 예제로 보이기 위함입니다.

인스턴스 이름

꼭 기억해야할 것 한 가지, UnrealScript 안에서 접근하려는 오브젝트는 반드시 그 InstanceName 을 고유하게 설정해야 합니다. 그래야 씬 안에 있는 그 엘리먼트를 식별하고 그 오브젝트로의 리퍼런스를 구할 수 있는 것입니다. 예제에서는 모든 엘리먼트가 나중에 접근할 필요가 없음에도 InstanceName 이 설정되어 있으며, 가장 눈여겨볼 것은 텍스트 입력 컴포넌트와 함께 가는 라벨 셋입니다. 지금 우리는 이런 스태틱 라벨에 접근할 필요가 없습니다. 그러나 메뉴 문구를 현지화하는 경우, 당연히 그런 엘리먼트에 접근해야 할 것입니다.

instance_name.jpg

enableInitCallback 콜백 초기화 켜기

UnrealScript 가 CLIK 위젯 통지를 받도록 하려면, Flash 의 CLIK 위젯에 있는 enableInitCallback 프로퍼티를 켜야 합니다. UnrealScript 내부를 접근해야 하는 위젯은 WidgetInitialzed (위젯 초기화됨) 콜백을 받을 수 있도록 이 프로퍼티를 켜 줘야 합니다. 이 프로퍼티는 디폴트로 켜져 있으나, UnrealScript 가 몰라도 되는 오브젝트에는 끄는 것이 좋습니다.

커서

스케일폼 UI 에 커서를 표시하는 것은 매우 간단합니다. 커서 그래픽을 사용하는 씬에 무비 클립을 추가하고 나서, 매번 업데이트마다 커서 무비 클립의 위치를 마우스 위치로 설정하는 ActionScript 도 조금 추가해 주면 됩니다.

커서 무비클립은 커서 그래픽을 스테이지로 임포트하고, 그것을 무비클립 심볼로 변환하여 만듭니다. 그런 다음 Actions 레이어 바로 아래 있으면서 다른 모든 레이어보다는 위에 있는 Cursor 레이어에 놓습니다.

ActionScript 를 추가하려면:

  1. 커서 무비클립을 선택하고 F9 키를 눌러 ActionScript 에디터를 엽니다.
  2. 아래 코드를 추가합니다:
Cursor ActionScript
onClipEvent(enterFrame)
{
   _X = _root._xmouse;
   _y = _root._ymouse;
}

이미지

플래시 내 씬에서 사용되는 이미지는 씬과 함께 자동으로 임포트 가능한데, 적절히 설정해 줘야 문제가 생기지 않습니다.

임포트할 이미지를 준비하려면:

  1. Library 패널에서 이미지를 선택하고, 우클릭한 다음, Properties 를 선택합니다.
    image_properties_menu.jpg
  2. Bitmap properties 대화창에서 Allow Smoothing 을 체크하고 CompressionLoseless (PNG/GIF) 로 설정합니다.
    image_properties.jpg
  3. advanced_button.jpg 버튼을 클릭하여 고급 프로퍼티를 표시합니다.
  4. Linkage 섹션에서 Export for ActionScript 를 켜고, Identifier 필드에 있는 이미지 이름에서 (마침표를 포함해) 파일 확장자를 지웁니다.
    image_linkage.jpg
  5. ok_button.jpg 버튼을 클릭해 변경내용을 저장합니다.
  6. 마지막으로 원본 소스 이미지 파일은 SWF 파일과 같은 이름의 폴더(SWF 파일과 같은 디렉토리)에 놓아야 합니다.
    folder_images.jpg

씬 임포트


플래시에서 씬 셋업을 마치고나면 게임내에서 사용할 수 있도록 언리얼로 전송해야 합니다. 첫 단계는 플래시 안에서 씬을 .swf 파일로 퍼블리싱하는 것입니다. 이 작업은 Scaleform Launcher 를 사용하여 씬을 미리볼 때 자동으로 일어나는 일이지만, File > Publish 를 선택하거나 Shift + F12 를 눌러 수동으로 퍼블리싱할 수도 있습니다.

publish_menu.jpg

퍼블리싱된 .swf 파일의 위치는 [GameName]\Flash 폴더 내 언리얼로 임포트시키려는 .swf 파일의 패키지 이름으로 된 폴더 안에 있어야 합니다. 이 폴더는 .swf 파일이 임포트될 패키지에 정확히 일치되며, 임포트 도중 변경할 수 없습니다. 선택적으로 이 패키지 안에 하위폴더를 두어 패키지 안에 그룹을 나타낼 수 있습니다.

folder_package.jpg

올바른 위치로 .swf 파일이 퍼블리싱되도록 하는 가장 쉬운 방법은, 단순히 실제 Flash (.fla) 파일을 원하는 위치에 바로 저장하는 것입니다. 퍼블리싱 파일도 디폴트로 같은 위치에 생성됩니다.

씬이 퍼블리싱된 이후, 언리얼 에디터콘텐츠 브라우저 를 통해, 또는 GFXIMPORT 커맨드렛 을 사용하여 언리얼로 임포트하면 됩니다. 이 예제에서는 콘텐츠 브라우저를 통한 임포트로 충분합니다.

  1. 언리얼 에디터를 열고 콘텐츠 브라우저로 가서 import_button.jpg 버튼을 클릭합니다.
  2. 열리는 파일 브라우저의 파일 종류 필터를 SWF Movie (.swf) 로 변경한 다음 퍼블리싱된 .swf 파일 위치로 이동합니다.
  3. 파일을 선택하고 open_button.jpg 버튼을 클릭합니다.
  4. 임포트 대화창의 패키지, 그룹, 이름 필드가 모두 채워져 회색으로 표시됩니다.
    import_dialog.jpg
    디폴트 세팅으로 잘 돌아갈 것입니다. ok_button.jpg 버튼을 눌러 씬을 임포트합니다.
  5. 임포트 프로세스가 완료되면 거기 들어있는 SWF 와 이미지가 전부 콘텐츠 브라우저에 나타날 것입니다.
    import_success.jpg

씬 연결


아래 UnrealScript 클래스가 우리 스케일폼 UI 예제를 구동시키는 것입니다. GFxMoviePlayer 클래스는 모든 스케일폼 UI 에 대한 베이스 클래스입니다. Movie 프로퍼티를 통해 SWF 파일과 연관되고, 그 이후 이벤트를 받고 명령을 전달함은 물론, 연관된 UI 내 엘리먼트에 접근하기도 합니다.

막 시작하려는 경우 UnrealScript 프로젝트를 새로 추가하는 법에 대한 정보는 Custom UnrealScript Projects KR 페이지를 참고하시기 바랍니다.

벌어지는 기본적인 프로세스는:

  • 무비 플레이어가 무비를 시작시킵니다. - Start()
  • 무비 플레이어가 초기화(initialize)됩니다. - Advance()
    • enableInitCallback 가 켜진 엘리먼트 전부에 대해 WidgetInitialized 가 호출됩니다.
    • 필요한 위젯에 리퍼런스가 저장됩니다. 즉 씬 안에 접근해야 하는 오브젝트는 리퍼런스를 저장해야 합니다.
    • 버튼의 클릭 이벤트에 대한 델리게이트가 할당됩니다. 버튼에 대한 WidgetInitialized 에 전달된 위젯이 이벤트 리스너를 추가시킬 수 있는 GFxCLICKWidget 가 되도록 하기 위해 위젯 바인딩 을 사용합니다.
  • 버튼이 눌리면 델리게이트가 호출됩니다.
    • SaveButton - 플레이어가 입력한 정보를 토대로 메시지가 변합니다.
    • ExitButton - UI 가 닫힙니다.

UIScene_Profile.uc
class UIScene_Profile extends GFxMoviePlayer;

/** UI 에 메시지를 표시하는 데 사용된 라벨로의 리퍼런스 */
var GFxObject MessageLabel;

/** 플레이어의 이름을 입력하는 데 사용된 텍스트 필드로의 리퍼런스 */
var GFxObject PlayerText;

/** 플레이어의 호칭을 입력하는 데 사용된 텍스트 필드로의 리퍼런스 */
var GFxObject TitleText;

/** 플레이어의 클랜을 입력하는 데 사용된 텍스트 필드로의 리퍼런스 */
var GFxObject ClanText;

/** 프로파일 정보를 저장하는 데 사용된 버튼으로의 리퍼런스. GFxCLIKWidget 을 기대하므로 위젯 바인딩을 추가해야 함  */
var GFxCLIKWidget SaveButton;

/** UI 를 닫는 데 사용된 버튼으로의 리퍼런스. GFxCLIKWidget 을 기대하므로 위젯 바인딩을 추가해야 함 */
var GFxCLIKWidget ExitButton;

// 무비를 시작하기 위해 UI 가 열렸을 때 호출
function bool Start(optional bool StartPaused = false)
{
	// 무비 재생 시작
    Super.Start();

	// 무비의 모든 오브젝트 초기화
    Advance(0);

    return true;
}

// 무비에 enableInitCallback 가 켜진 오브젝트 각각에 대해 자동으로 콜백 호출
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
{
    // 어느 위젯이 초기화되었는지 알아내어 적절히 처리
    switch(Widgetname)
    {
        case 'messageLabel':
        	// 플레이어한테 메시지를 표시하는 라벨로의 리퍼런스 저장
            MessageLabel = Widget;
            break;
        case 'playerText':
        	// 플레이어의 이름에 대한 텍스트 필드로의 리퍼런스 저장
            PlayerText = Widget;
            break;
        case 'titleText':
        	// 플레이어의 칭호에 대한 텍스트 필드로의 리퍼런스 저장
            TitleText = Widget;
            break;
        case 'clanText':
        	// 플레이어의 클랜에 대한 텍스트 필드로의 리퍼런스 저장
            ClanText = Widget;
            break;
        case 'saveButton':
        	// 프로파일 정보를 저장하는 버튼에 대한 리퍼런스 저장
		// 이벤트 리스너를 허용하기 위해 Widget 을 GFxCLIKWidget 으로 형 변환. WidgetBindings 참고
            SaveButton = GFxCLIKWidget(Widget);
            // 버튼이 눌렸을 때에 대한 델리게이트 추가
            SaveButton.AddEventListener('CLIK_click', SavePlayerData);
            break;
        case 'exitButton':
        	// UI 를 닫는 버튼으로의 리퍼런스 저장
		// 이벤트 리스너를 허용하기 위해 Widget 을 GFxCLIKWidget 으로 형 변환. WidgetBindings 참고
            ExitButton = GFxCLIKWidget(Widget);
            // 이 버튼이 눌렸을 때에 대한 델리게이트 추가
            ExitButton.AddEventListener('CLIK_click', CloseMovie);
            break;
        default:
        	// 찾는 위젯이 아니면 통과
            return Super.WidgetInitialized(Widgetname, WidgetPath, Widget);
    }

    return false;
}

// 입력된 데이터를 사용하여 메시지를 바꾸기 위해 추가된 델리게이트
//게임 실제 상황에서 이 데이터는 어딘가에 저장
function SavePlayerData(EventData data)
{
    // 왼쪽 마우스 버튼에만
    if(data.mouseIndex == 0)
    {
    	// 입력된 프로파일 정보를 사용하여 메시지 라벨의 텍스트 프로퍼티 설정
        MessageLabel.SetString("text", "Welcome,"@PlayerText.GetString("text")@"("$TitleText.GetString("text")@"in"@ClanText.GetString("text")$")");
    }
}

// 무비를 닫기 위해 추가된 델리게이트
function CloseMovie(EventData data)
{
    // 왼쪽 마우스 버튼에만
    if(data.mouseIndex == 0)
    {
    	// UI 닫기
        Close();
    }
}

defaultproperties
{
    // 사용할 임포트된 SWF
	MovieInfo=SwfMovie'UDNHud.UI_QuickStart'

    // 버튼에 대한 WidgetInitialized 에 전달된 Widget 이
    // GFxCLICKWidget 이 되도록 위젯 바인딩 설정
    WidgetBindings.Add((WidgetName="saveButton",WidgetClass=class'GFxCLIKWidget'))
    WidgetBindings.Add((WidgetName="exitButton",WidgetClass=class'GFxCLIKWidget'))

    // 무비에 대한 프로퍼티 설정을
    // TimingMode=TM_Real 로 하여 게임이 일시정지된 동안 메뉴가 실행되도록
    bDisplayWithHudOff=TRUE
    TimingMode=TM_Real
	bPauseGameWhileActive=TRUE
	bCaptureInput=true
}

씬 테스트


게임 내에서 씬을 테스트하여 예상대로 작동하나 확인할 때가 됐습니다. 아주 간단합니다. 실행시킬 맵과 맵이 로드되면 무비를 열어줄 키즈멧만 있으면 됩니다. 물론 언제 어떻게 어느 UI 를 로드하는지는 전적으로 그 UI 의 종류가 무엇이냐에 달렸습니다. HUD 는 항상 로드될 수 있도록 UnrealScript 를 통해 처리될 것입니다. 메인 메뉴는 앞서 설명했듯이 맵이 로드되면 키즈멧을 통해 로드해도 되고, 게임내 메뉴를 로드해도 됩니다. 테스트 목적이라면 키즈멧 쪽이 가장 쉽기는 하겠습니다.

키즈멧에서 스케일폼 무비를 열려면:

  1. Level Loaded (New Event > Level Loaded) 이벤트와 Open GFx Movie (New Action > GFx UI > Open GFx Movie) 액션을 추가합니다.
  2. Level Loaded 이벤트의 Beginning of Level 출력을 Open GFx Movie 액션의 In 입력에 연결합니다.
  3. 콘텐츠 브라우저에서 임포트된 SWF 를 선택하고 Open GFx Movie 액션의 프로퍼티에서 use_selected_button.jpg 버튼을 눌러 Movie 프로퍼티를 SWF 에 할당합니다.
  4. Movie Player Class 를 예전 섹션의 클래스로, 이 경우 UIScene_Profile 로 설정합니다. 예전 단계에서 할당된 무비를 구동시키는 클래스입니다.
  5. (메뉴이지 HUD 는 아니라 가정하고) Take FocusCapture Input 프로퍼티를 켜서 메뉴에 포커스를 주고 입력을 받을 수 있도록 합니다.

구성이 완료되면 이런 모습입니다:

kismet_setup.jpg

이제 pie_button.jpg 버튼을 사용하여 맵을 플레이하면 스케일폼 UI 가 표시됩니다.

quickstart_load.jpg

마우스를 움직이면 커서가 따라 움직이며, 두 버튼에도 적합한 동작, 메시지 변경과 UI 닫기가 발생합니다.

quickstart.jpg