UDN
Search public documentation:

MobileMenuTechnicalGuideKR
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 홈 > 유저 인터페이스와 HUD > 모바일 메뉴 테크니컬 가이드

모바일 메뉴 테크니컬 가이드


개요


모바일 메뉴 시스템은 터치 인풋에 반응하는 유저 인터페이스를 모바일 디바이스용으로 생성하는 것입니다. 이 시스템은 개별 메뉴나 인터페이스를 나타내기 위한 씬 개념을 사용하며, 각 씬에는 버튼이나 이미지 또는 텍스트 라벨같은 콘트롤을 몇 이든 어떤 조합으로든 포함될 수 있습니다.

mobilemenuscene.jpg

모바일 메뉴 시스템이 보통 메인 및 일시정지 등의 메뉴 제작에 쓰이기는 하지만, 이러한 씬은 게임플레이가 발행중이지 않을 때 표시되는 메뉴용으로만 쓰이는 것은 아닙니다. 게임플레이가 계속되는 와중에 겹쳐 표시할 수도 있으며, 발생한 입력의 위치와 종류에 따라 입력을 받을 수도 통과시킬 수도 있습니다. 이를 통해 모바일 메뉴 시스템이 표준 인풋 존 콘트롤을 증폭시켜 화면상에 커스텀 콘트롤을 만들어 내거나 HUD 생성을 위한 조직적인 방법을 제공하는 것도 가능합니다.


전에 언급한 대로 씬이란 개별 인터페이스를 이루는 관련 콘트롤 그룹을 담은 용기입니다. 씬은 게임이 처음 실행될 때 표시되는 메인 메뉴가 될 수도 있고, 게임을 일시정지할 때 표시되는 메뉴가 될 수도 있고, 화면 하단에 놓인 버튼 바가 될 수도 있습니다. 각 씬에는 경계 (Left, Top, Width, Height) 세트가 있으며, 거기서 입력을 처리하는 콘트롤 배열도 있습니다.

MobileMenuScene

MobileMenuScene 클래스는 모바일 메뉴 시스템의 모든 씬에 대한 베이스 클래스입니다. 기본적인 씬의 작동방식을 정의하며, 사용자로부터의 입력을 처리하고, 콘트롤을 그리는 등의 역할을 합니다.

MobileMenuScene 속성

Display 표시

  • SceneCaptionFont 씬 캡션 폰트 - 씬의 모든 버튼 캡션을 그리는 데 사용할 단일 폰트를 지정합니다.
  • Opacity 불투명도 - 씬과 그 콘트롤 전부의 전체적인 불투명도입니다.

General 일반

  • MenuName 메뉴 이름 - 씬을 식별하는 데 사용되는 고유명을 지정합니다.
  • MenuObjects 메뉴 오브젝트 - 씬의 콘트롤 오브젝트를 전부 담는 배열입니다.
  • InputOwner 인풋 오너 - 씬의 관리를 담당하는 MobilePlayerInput 을 가리킵니다.
  • bSceneDoesNotRequireInput 씬이 입력을 요하지 않음? - 참이면 씬은 터치 입력을 받지 않습니다. 거짓이면 입력이 씬에 전달되어 처리됩니다. 디폴트는 거짓입니다. 이 옵션을 참으로 설정하면 씬은 HUD가 됩니다.

Position 위치

  • [Left/Top] [왼쪽/위쪽] - 씬의 [왼쪽/위쪽] 가장자리의 픽셀 단위 [가로/세로] 위치입니다. 주: 디폴트 속성에서 [0.0, 1.0] 범위의 상대적 위치로 지정할 수도 있으나, 씬이 초기화되면 픽셀로 변환됩니다.
  • [Width/Height] [폭/높이] - 씬의 [폭/높이]입니다. 주: 디폴트 속성에서 [0.0, 1.0] 범위의 상대적 위치로 지정할 수도 있으나, 씬이 초기화되면 픽셀로 변환됩니다.
  • bRelative[Left/Top/Width/Height] 상대적 [왼쪽/위쪽/폭/높이]? - 참이면 디폴트 속성에 정의된 Left 값은 [0.0, 1.0] 범위의 상대값으로 간주되며, 씬이 초기화될 때 절대 픽셀 값으로 변환됩니다.
  • bApplyGlobalScale[Left/Width] [왼쪽/폭]에 글로벌 스케일 적용? - 참이면 [Left/Width] 값에 X 방향으로 글로벌 스케일 인수를 곱해줍니다. 이를 통해 화면 해상도와 픽셀 밀도가 다른 여러 디바이스에서 적절한 위치를 잡을 수 있습니다.
  • bApplyGlobalScale[Top/Height] [위쪽/높이]에 글로벌 스케일 적용? - 참이면 [Top/Height] 값에 Y 방향으로 글로벌 스케일 인수를 곱해줍니다. 이를 통해 화면 해상도와 픽셀 밀도가 다른 여러 디바이스에서 적절한 위치를 잡을 수 있습니다.

Sound 사운드

  • UI[Touch/UnTouch]Sound UI [터치/언터치] 사운드 - [터치/언터치] 이벤트가 발생할 때 재생할 사운드큐를 가리킵니다.

MobileMenuScene 함수

Display 표시

  • GetGlobalScale[X/Y] 글로벌 스케일 구하기 - 게임이 실행되고 있는 디바이스에 따라 가로 세로 글로벌 스케일 인수를 반환합니다.
  • RenderScene [Canvas] [RenderDelta] 렌더 씬 - 씬을 렌더링하기 위해 InputOwner 가 호출합니다. 씬이 그에 속한 콘트롤 전부에서 단순히 RenderObject() 를 호출하는 것입니다.
    • Canvas 캔버스 - 씬을 그리는 데 사용할 Canvas 를 가리킵니다.
    • RenderDelta 렌더 델타 - 지난 렌더 사이클 이후로 경과된 기간을 담습니다.

General 일반

  • InitMenuScene [PlayerInput] [ScreenWidth] [ScreenHeight] 메뉴 씬 초기화 - 씬과 그 콘트롤을 초기화시키기 위해 엔진이 호출합니다.
    • PlayerInput 플레이어 인풋 - 씬 관리를 담당하는 MobilePlayerInput 을 가리킵니다.
    • ScreenWidth 화면 폭 - 게임이 실행되는 디바이스의 화면 폭을 담습니다.
    • ScreenHeight 화면 높이 - 게임이 실행되는 디바이스의 화면 높이를 담습니다.
  • Opened [Mode] 열림 - 씬이 열렸을 때 호출됩니다.
    • Mode 모드 - MobilePlayerInputOpenMenuScene() 함수로 전달되는 옵션 문자열을 담습니다.
  • MadeTopMenu 탑 메뉴가 됨 - 씬이 열리거나 다른 씬이 닫히거나 해서 스택의 맨위 씬이 되면 호출됩니다.
  • Closing 닫는중 - 씬 닫기 요청이 있은 후 실제 닫기 프로세스가 발생하기 전에 호출됩니다. 씬 닫기를 허용할 때는 참을, 닫기를 덮어써 열린 상태로 남아있으려면 거짓을 반환합니다.
  • Closed 닫힘 - 씬이 닫혀 Inputowner 의 씬 스택에서 제거되었을 때 호출됩니다.
  • CleanUpScene 씬 비우기 - 네이티브. 모든 씬 참조 및 메모리를 비웁니다.
  • FindMenuObject [Tag] 메뉴 오브젝트 찾기 - MenuObjects 배열에서 주어진 Tag 에 일치하는 콘트롤을 반환합니다.
    • Tag 태그 - 검색할 콘트롤의 Tag 입니다.

Input 인풋

  • OnTouch [Sender] [TouchX] [TouchY] [bCancel] 터치시 - 씬이 소유한 콘트롤에 (언터치 이벤트 상의) 터치가 발생했을 때 엔진이 호출하는 이벤트 토막입니다. 콘트롤 터치용 커스텀 함수성을 제공하려면 서브클래스에서 이를 덮어써야 합니다.
    • Sender 보낸이 - 터치된 MobileMenuObject 를 가리킵니다.
    • Touch[X/Y] 터치[X/Y] - 터치의 픽셀 단위 [가로/세로] 위치를 담습니다.
    • bCancel 취소? - 참이면 터치는 사용자가 아닌 시스템 이벤트 같은 외부 요인에 의해 취소된 것입니다.
  • OnSceneTouch [EventType] [TouchX] [TouchY] 씬 터치시 - 디바이스에 터치 이벤트가 발생할 때 엔진이 호출하는 이벤트 토막입니다. 입력이 처리되었다면 참을, 입력을 전달하려면 거짓을 반환합니다. 씬의 콘트롤에 꼭 직접 관계되지 않은 커스텀 터치 입력 처리 기능을 제공하기 위해서는 서브클래스에서 이를 덮어써야 합니다. ALERT! 중요: 현재 이는 씬에 외부 터치 입력 처리를 허용하기 위해 씬의 경계 밖 터치가 발생했을 때만 호출되고 있으나, 설명처럼 범용 입력 처리기로 사용되게 하기 위해 재작업 예정입니다.
    • EventType 이벤트 타입 - 터치 이벤트의 EZoneTouchEvent 유형을 담습니다. 터치 이벤트 유형에 관련된 상세 정부는 Mobile Input System KR 페이지를 참고하시기 바랍니다.
    • Touch[X/Y] 터치[X/Y] - 터치의 픽셀 단위 [가로/세로] 위치를 담습니다.
  • MobileMenuCommand [Command] 모바일 메뉴 명령 - 실행 또는 콘솔 명령을 실행합니다. 현재 구현되지 않았습니다.
    • Command 명령 - 실행시킬 실행 또는 콘솔 명령입니다.

콘트롤


콘트롤은 사용자에게 정보를 표시하거나 터치 입력을 받기 위해 씬에 추가되는 개별 컴포넌트입니다. 그러나 콘트롤 자체가 어떤 입력을 실제로 처리하는 것은 아닙니다. 디폴트로 모든 입력 처리를 담당하는 것은 씬입니다. 씬 자체에는 시각적인 성분이 없으며, 콘트롤이 씬의 시각적인 부분을 이루는 것입니다.

MobileMenuObject

MobileMenuObject 클래스는 모바일 메뉴 시스템의 모든 콘트롤에 대한 베이스 클래스입니다. 콘트롤은 'touched'와 'not touched'의 두 가지 상태가 있으며, 외형 및/또는 그 각각의 상태에 대한 작동방식도 별개의 것으로 구분 가능합니다. 디폴트 상태는 'not touched'로, 사용자가 터치할 때까지 그대로 유지됩니다. 터치되면 'touched' 상태가 되었다가, 사용자가 더이상 터치하지 않으면 'not touched' 상태로 되돌아갑니다.

주: 위의 용어 "상태"는 UnrealScript 의 State 기능을 말하지 않습니다. 그보다는 단지 콘트롤이 사용자로부터의 입력에 따라 각기 다른 외형 및/또는 작동방식을 가질 수 있음을 나타내기 위해 쓰인 것입니다.

MobileMenuObject 속성

Display 표시

  • bIsHidden 숨겨짐? - 참이면 콘트롤은 렌더링되지 않습니다.
  • bIsHighlighted 반전됨? - 참이면 콘트롤은 '반전된' 상태, 즉 선택된 라디오 버튼과 같은 상태가 됩니다.
  • Opacity 불투명도 - 콘트롤의 불투명도입니다.

General 일반

  • bHasBeenInitialized 초기화되었는지? - 참이면 콘트롤은 현재 화면 크기에 맞게 초기화된 것입니다.
  • Tag 태그 - 콘트롤 식별에 쓰이는 고유명을 지정합니다.
  • OwnerScene 오너 씬 - 콘트롤이 속하는 MobileMenuScene 을 가리킵니다.

Input 입력

  • [Top/Bottom/Left/Right]Leeway [상/하/좌/우] 여유치 - 콘트롤의 최[상/하/좌/우]단 가장자리를 따라 힛박스 밖으로 얼마까지 떨어진 터치를 콘트롤의 것으로 간주할 것인지를 지정합니다.
  • bIsActive 활성인지? - 참이면 이 콘트롤은 활성인 것으로 간주하고 탭을 받습니다.
  • bIsTouched 터치되었는지? - 참이면 현재 콘트롤 위로 터치 이벤트가 발생하고 있습니다.
  • InputOwner 인풋 오너 - 콘트롤 관리를 담당하는 MobilePlayerInput 을 가리킵니다.

Position 위치

  • [Left/Top] [왼쪽/위쪽] - 콘트롤 [왼쪽/위쪽] 가장자리의 픽셀 단위 [가로/새로] 위치입니다. 주: 이는 디폴트 속성에서 [0.0, 1.0] 범위의 상대 위치로 지정할 수도 있습니다만, 콘트롤이 초기화되면 픽셀로 변환됩니다.
  • [Width/Height] [폭/높이] - 콘트롤의 [폭/높이]입니다. 주: 이는 디폴트 속성에서 [0.0, 1.0] 범위의 상대 위치로 지정할 수도 있습니다만, 콘트롤이 초기화되면 픽셀로 변환됩니다.
  • bRelative[Left/Top/Width/Height] 상대적 [왼쪽/위쪽/폭/높이]? - 참이면 디폴트 속성에서 지정된 [Left/Top/Width/Height] 값은 [0.0, 1.0] 범위의 상대값으로 간주되며, 콘트롤이 초기화될 때 절대 픽셀값으로 변환됩니다.
  • bApplyGlobalScale[Left/Width] 글로벌 스케일 [왼쪽/폭] 적용? - 참이면 [Left/Width] 값에 X 방향으로 글로벌 스케일 인수를 곱해줍니다. 이를 통해 화면 해상도와 픽셀 밀도가 다른 여러 디바이스에서 적절한 위치를 잡을 수 있습니다.
  • bApplyGlobalScale[Top/Height] 글로벌 스케일 [위쪽/높이] 적용? - 참이면 [Top/Height] 값에 Y 방향으로 글로벌 스케일 인수를 곱해줍니다. 이를 통해 화면 해상도와 픽셀 밀도가 다른 여러 디바이스에서 적절한 위치를 잡을 수 있습니다.
  • bHeightRelativeToWidth 높이가 폭에 상대적? - 참이면 콘트롤 생성시 디폴트 속성에 지정된 Height 는 실제 Width 에 대해 ([0.0, 1.0] 범위의) 상대값으로 간주됩니다. 콘트롤의 실제 Height 는 지정된 Height 에 실제 Width 를 곱하여 계산됩니다.
  • [X/Y]Offset [X/Y]오프셋 - 콘트롤의 경계에 상대적인 [가로/세로] 오프셋을 지정하며, 콘트롤을 그리는 데 사용 가능합니다. 디폴트로 이 값은 [0.0, 1.0] 범위의 퍼센트 값이라 가정됩니다.
  • b[X/Y]OffsetIsActual [X/Y]오프셋 실제? - 참이면 [X/Y]Offset 값은 픽셀 값인 것으로 가정됩니다.

MobileMenuObject 함수

  • InitMenuObject [PlayerInput] [Scene] [ScreenWidth] [ScreenHeight] 메뉴 오브젝트 초기화 - 콘트롤 초기화를 위해 엔진이 호출합니다.
    • PlayerInput 플레이어 인풋 - 콘트롤 관리를 담당하는 MobilePlayerInput 를 가리킵니다.
    • Scene 씬 - 콘트롤이 속하는 MobileMenuScene 를 가리킵니다.
    • Screen[Width/Height] 화면 [폭/높이] - 게임이 실행되는 디바이스 화면의 [폭/높이]를 담습니다.
  • RenderObject [Canvas] 렌더 오브젝트 - 콘트롤을 화면에 그리기 위해 각 프레임에 속하는 콘트롤, 씬에 의해 호출됩니다.
    • Canvas 캔버스 - 콘트롤을 그리는 데 사용되는 Canvas 를 가리킵니다.

MobileMenuButton

MobileMenuButton 클래스는 터치했을 때 일정 동작을 하는 이미지 및/또는 텍스트를 표시할 수 있는 콘트롤입니다. 디폴트로 (bIsActive=true) 입력을 받는 유일한 콘트롤입니다. 버튼에 터치가 (엄밀히 'untouch' 이벤트가) 발생하면, 그를 소유하는 씬은 통지를 받습니다. 버튼이 'untouched' 상태일 때는 (bIsTouched=false) 한 이미지를, 'touched' 상태일 때는 (bIsTouched=true) 다른 이미지를 표시합니다.

control_buttons.jpg

Properties 속성

  • Images 이미지 - 각 상태마다 하나씩, 버튼을 렌더링하는 데 사용되는 Texture2D 둘로 된 배열입니다. [0] 요소는 'not touched' 상태에 사용되며, [1] 요소는 'touched' 상태에 사용됩니다.
  • ImagesUVs 이미지 UV - 각 상태마다 하나씩, 버튼을 렌더링하는 데 사용되는 Images 텍스처 구역 지정 UVCoords 둘로 된 배열입니다. [0] 요소는 'not touched' 상태에 사용되며, [1] 요소는 'touched' 상태에 사용됩니다.
  • ImageColor 이미지 컬러 - 버튼 이미지를 변조시킬 색을 지정합니다.
  • Caption 캡션 - 옵션이며, 버튼에 표시할 텍스트 라벨을 지정합니다.
  • CaptionColor 캡션 컬러 - Caption 텍스트를 그리는 데 사용되는 색을 지정합니다.

Functions 함수

  • RenderCaption [Canvas] 렌더 캡션 - 캡션이 지정된 경우, 버튼의 Caption 텍스트를 그립니다.
    • Canvas 캔버스 - 텍스트를 그리는 데 사용할 Canvas 를 가리킵니다.

MobileMenuImage

MobileMenuImage 클래스는 이미지를 텍스처나 텍스처 일부의 형태로 화면상에 표시하는 클래스입니다. 입력을 받지 않는 콘트롤, 즉 이미지 상의 터치 이벤트는 등록되지 않고 씬의 OnTouch() 이벤트로 전송되며, 이 클래스는 본질적으로 장식 콘트롤이 됩니다.

Properties 속성

  • Image 이미지 - 이미지를 그릴 때 사용할 텍스처를 지정하는 데 쓰이는 Texture2D 입니다.
  • ImageDrawStyle 이미지 드로 스타일 - 이미지를 그리는 데 사용할 MenuImageDrawStyle 을 지정합니다.
    • IDS_Normal 이드스_보통 - 지정된 텍스처 구역을 스케일 조절하지 않고 이미지 경계에 맞도록 잘라내어 그립니다.
    • IDS_Stretched 이드스_늘임 - 지정된 텍스처 구역을 이미지 경계에 맞도록 스케일 조절하여 그립니다.
    • IDS_Tile 이드스_타일 - 좌상단 구역은 유지한 채, 이미지 경계에 맞도록 구역의 폭과 높이를 변경합니다. 지정된 구역이 이미지 경계보다 크면 이미지를 잘라내고, (구역이 풀 텍스처라 가정할 때) 구역이 이미지 경계보다 작으면 이미지를 이어붙입니다. 주: 아틀라스 텍스처를 사용할 때는 작동법을 종잡을 수 없게 되니 이 옵션은 피하는 것이 좋습니다.
  • ImageUVs 이미지 UV - 이미지를 그릴 때 사용할 Image 텍스처의 구역을 지정하는 UVCoords 입니다.
  • ImageColor 이미지 컬러 - 이미지를 그릴 때 Image 텍스처를 변조시킬 색을 지정합니다.

MobileMenuLabel

MobileMenuLabel 클래스는 화면상에 텍스트 문자열을 표시하는 클래스입니다. 커스텀/다이내믹 데이터나 텍스트를 사용자에게 표시할 때 좋습니다. 이 콘트롤은 입력을 받지 않으며, 터치 이벤트는 등록되지 않고 씬의 OnTouch() 이벤트로 전송됩니다.

Properties 속성

  • Caption 캡션 - 화면상에 표시되는 라벨의 텍스트 문자열을 지정합니다.
  • TextFont 텍스트 폰트 - 텍스트를 그리는 데 사용할 폰트를 지정합니다.
  • TextColor 텍스트 컬러 - 라벨이 터치되지 않았을 때 텍스트를 그리는 데 사용할 색을 지정합니다.
  • TouchedColor 터치된 컬러 - 라벨이 터치될 때 텍스트를 그리는 데 사용할 색을 지정합니다.
  • Text[X/Y]Scale 텍스트 [X/Y] 스케일 - 텍스트를 그리는 데 사용할 [가로/세로] 스케일 인수를 지정합니다.
  • bAutoSize - 참이면 라벨의 WidthHeight 는 매 드로 사이클마다 렌더링되는 텍스트의 크기에 맞게 조절됩니다. 거짓이면 라벨의 WidthHeight 는 변하지 않습니다.

커스텀 콘트롤

기본 내장 콘트롤은 (위의 설명대로 버튼, 이미지, 라벨 등) 몇 없는 반면, 약간의 독창성을 발휘하여 어떤 종류의 콘트롤도 실용적으로 조합해 낼 수 있습니다. 예로 각각에 해당하는 라벨이 붙어 있는 버튼이 여럿 있는데, 그 중 하나가 눌리면 해당 버튼은 '선택' 이미지로 바뀌고 나머지는 '미선택' 이미지로 바뀌는 버튼 그룹을 들어볼 수 있겠습니다. 라디오 버튼 그룹의 느낌을 낼 수 있는 것입니다.

좀 더 복잡한 콘트롤 외형을 내기 위해 씬 내 콘트롤을 조합하는 방법은 씬에 많은 커스텀 로직을 필요로 합니다. 그리 복잡한 콘트롤을 재사용하려는 경우 이와 같은 것이 이상적이지 않다는 것은 명확합니다. 콘트롤이 입력을 바로 처리하거나 받지는 않는다 쳐도, 좀 더 복잡한 유형의 재사용 가능 콘트롤을 만들려면 시스템에 부가적인 변경 작업을 해 줘야 합니다. 예로 일반 입력을 다룬 다음 그 각각의 콘트롤에서 처리할 수 있도록 전달해 주려면 MobileMenuScene 의 서브클래스를 만들어야 할 수도 있습니다. 이런 식으로 커스텀 콘트롤이 스와이프 동작에 따른 스크롤 목록처럼, 터치 입력에 직접 반응하도록 하는 복잡한 작동법도 가능해 집니다. (커스텀 리스트 콘트롤 부분 참고)

메뉴 씬 작업하기


모바일 메뉴 시스템 사용법은 매우 간단합니다. 새로운 커스텀 메뉴에 콘트롤을 더한 다음, 인풋 시스템 초기화 이전의 어느 시점에서든 열거나 닫을 수 있습니다. 이는 MobilePlayerInput 클래스가 메뉴 시스템 관리를 담당하기에 그렇습니다. 터치 입력 처리는 메뉴 자체 내에서 수행되며, 어느 시나리오든 실제적으로 허용될 만큼 유연합니다.

콘트롤 만들기

씬에 콘트롤을 더하는 것은 일반적으로 씬 클래스의 defaultproperties 블록 내에 서브-오브젝트를 만들어 수행합니다. 각 콘트롤은 서브-오브젝트로 생성된 이후 씬의 MenuObjects 배열에 추가됩니다. 콘트롤이 defaultproperties 블록 내에 생성되는 순서는 그다지 중요하지 않으나, MenuObjects 배열에 추가되는 순서는 콘트롤이 렌더링되고 입력을 받는 순서를 결정하기에 매우 중요합니다.

콘트롤을 새로 만들어 MenuObjects 배열에 추가시키기 위한 전형적인 서브오브젝트 블록 형태는 다음과 같습니다:

Begin Object Class=MobileMenuButton Name=ExploreButton
   Tag="EXPLORE"
   Left=0.35
   Top=0.35
   Width=140
   Height=24
   bRelativeLeft=true
   bRelativeTop=true
   TopLeeway=20
   Images(0)=Texture2D'CastleUI.menus.T_CastleMenu2'
   Images(1)=Texture2D'CastleUI.menus.T_CastleMenu2'
   ImagesUVs(0)=(bCustomCoords=true,U=306,V=220,UL=310,VL=48)
   ImagesUVs(1)=(bCustomCoords=true,U=306,V=271,UL=310,VL=48)
End Object
MenuObjects(0)=ExploreButton

이 예제에서 살펴보면, 버튼은 MenuObjects 배열에서 첫 항목으로 (0 요소) 명시적 추가되어 있습니다. 이런 식으로 순서를 명시적으로 지정하면 defaultproperties 블록 내에 원하는 순서대로 콘트롤을 만들 수 있습니다.

같은 버튼을 MenuObjects 배열 끝에 밀어넣는 것은 이런 식으로도 간단히 가능합니다:

Begin Object Class=MobileMenuButton Name=ExploreButton
   Tag="EXPLORE"
   Left=0.35
   Top=0.35
   Width=140
   Height=24
   bRelativeLeft=true
   bRelativeTop=true
   TopLeeway=20
   Images(0)=Texture2D'CastleUI.menus.T_CastleMenu2'
   Images(1)=Texture2D'CastleUI.menus.T_CastleMenu2'
   ImagesUVs(0)=(bCustomCoords=true,U=306,V=220,UL=310,VL=48)
   ImagesUVs(1)=(bCustomCoords=true,U=306,V=271,UL=310,VL=48)
End Object
MenuObjects.Add(ExploreButton)

이 방법을 사용할 때 중요한 점은, 콘트롤을 만들어 바라는 순서대로 MenuObjects 배열에 추가시킬 수 있다는 것입니다.

어떤 방법을 사용하든, 서브-오브젝트 블록에 대한 구문은 동일하게 유지됩니다. 각 블록은 아래와 같이 시작됩니다:

Begin Object Class=[ControlClass] Name=[ControlName]

이는 새로운 ControlClass 유형의 서브오브젝트가 ControlName 이란 이름으로 생성됨을 의미합니다. 여기에 콘트롤의 속성에 대한 값 설정이 이어지며, 보통 읽기 좋은 형태로 나타나게 됩니다. 마지막으로 모든 속성 값을 설정한 이후, 다음 블록으로 마무리합니다:

End Object

이제 이 서브 오브젝트는 MenuObjects 배열에 할당할 때와 마찬가지로, 그 이름을 통해 defaultproperties 블록에 참조시킬 수 있습니다.

실제 기능은 없지만 배경 이미지에 버튼 하나로 된 단순한 씬을 구성해 보자면 이와 같습니다:

class MobileMenuExample extends MobileMenuScene;

defaultproperties
{
   Left=0
   Top=0
   Width=1.0
   Height=180
   bRelativeWidth=true

   Begin Object Class=MobileMenuImage Name=Background
      Tag="Background"
      Left=0
      Top=0
      Width=1.0
      Height=1.0
      bRelativeWidth=true
      bRelativeHeight=true
      Image=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImageDrawStyle=IDS_Stretched
      ImageUVs=(bCustomCoords=true,U=0,V=30,UL=1024,VL=180)
   End Object
   MenuObjects.Add(Background)

   Begin Object Class=MobileMenuButton Name=ExploreButton
      Tag="EXPLORE"
      Left=0.35
      Top=0.35
      Width=140
      Height=24
      bRelativeLeft=true
      bRelativeTop=true
      TopLeeway=20
      Images(0)=Texture2D'CastleUI.menus.T_CastleMenu2'
      Images(1)=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImagesUVs(0)=(bCustomCoords=true,U=306,V=220,UL=310,VL=48)
      ImagesUVs(1)=(bCustomCoords=true,U=306,V=271,UL=310,VL=48)
   End Object
   MenuObjects.Add(ExploreButton)
}

이 결과는 아래와 같습니다:

addcontrols.jpg

메뉴 관리하기

모바일 메뉴 시스템은 MobilePlayerInput 클래스에 의해 관리됩니다. 여기에는 씬 여닫기에 관련된 함수성은 물론 렌더링하라고 알리는 것도, 사용자로부터의 입력을 씬과 그 콘트롤에 전달하는 것도 포함됩니다.

씬 스택

언제든지 다수의 씬을 열 수 있습니다. 열린 씬 전부는 MobilePlayerInput 내 스택(배열)에 담깁니다. 마지막으로 열린 씬은 항상 스택 맨위에 위치합니다. 입력은 씬 스택의 위에서 아래로 필터링됩니다. 스택 맨위의 씬이 입력을 처리하면, 스택에서 그 아래의 씬은 그 입력에 접근하지 못합니다. 스택의 씬은 아래에서 위로 렌더링되기에, 맨위에 있는 씬이 다른 씬 위에 렌더링되게 됩니다.

메뉴 씬 열기

MobilePlayerInput 클래스는 메뉴 씬을 여는 데 사용되는 여러가지 함수를 포함하고 있습니다.

  • OpenMenuScene [SceneClass] [Mode] 메뉴 씬 열기 - 주어진 클래스의 메뉴 씬을 새로 엽니다. 열린 씬으로의 참조를 반환합니다.
    • SceneClass 씬 클래스 - 열 메뉴 씬 클래스를 지정합니다. MobileMenuScene 의 서브클래스여야 합니다.
    • Mode 모드 - 옵션. 씬의 Opened() 함수에 전달할 문자열을 지정합니다.
  • OpenMobileMenu [MenuClassName] 모바일 메뉴 열기 - 문자열 형태로 주어진 클래스의 메뉴 씬을 엽니다.
    • MenuClassName 메뉴 클래스 이름 - 열 메뉴 씬 클래스 이름을 문자열 형태로 지정합니다.
  • OpenMobileMenuMode [MenuClassName] [Mode] 모바일 메뉴 모드 열기 - 문자열 형태로 주어진 클래스의 메뉴 씬을 옵션 모드로 엽니다.
    • MenuClassName 메뉴 클래스 이름 - 열 메뉴 씬 클래스 이름을 문자열 형태로 지정합니다.
    • Mode 모드 - 옵션. 씬의 Opened() 함수에 전달할 문자열을 지정합니다.

메뉴 씬 닫기

MobilePlayerInput 클래스는 메뉴 씬을 닫는 데 사용할 수 있는 함수가 둘 포함되어 있습니다.

  • CloseMenuScene [SceneToClose] 메뉴 씬 닫기 - 지정된 메뉴 씬을 닫습니다.
    • SceneToClose 닫을 씬 - 닫을 씬을 가리킵니다.
  • CloseAllMenus 모든 메뉴 닫기 - 씬 스택에 있는 메뉴 씬을 전부 닫습니다.

메뉴 씬 렌더링하기

MobilePlayerInput 클래스는 씬 스택에 있는 각 씬에게 매 프레임 렌더링 명령을 내리기도 합니다.

  • RenderMenus [Canvas Canvas] [RenderDelta] 렌더 메뉴 - 씬 스택에 있는 메뉴 전부를 렌더링하고자 엔진이 매 프레임 호출합니다.
    • Canvas 캔버스 - 씬을 그리는 데 사용할 Canvas 를 가리킵니다.
    • RenderDelta 렌더 델타 - 지난 렌더 사이클 이후 경과한 기간을 담습니다.

터치 입력

씬의 경계 내 화면에 사용자가 터치하면, 씬은 엔진으로부터 터치 입력 통지를 받습니다. 씬은 이러한 통지를 사용하여 터치 입력을 동작으로 해석합니다. 어느 씬에서 입력 통지를 갖는지를 결정하는 주요 방법은 둘 있습니다.

콘트롤 터치

활성 콘트롤이 터치되었을 때 씬은 콘트롤에서 (OnTouch() 이벤트를 통해) 통지를 받아, 씬이 터치 결과를 알아서 적당한 식으로 처리하도록 합니다. 이 이벤트는 사용자가 콘트롤을 "언터치"할 때, 즉 버튼을 누를 때가 아닌 버튼을 뗄 때만 호출됩니다.

  • OnTouch [Sender] [TouchX] [TouchY] [bCancel] 터치시 - 씬이 소유하는 콘트롤에 (Untouch 이벤트의) 터치가 발생했을 때 엔진이 호출하는 이벤트 토막입니다. 콘트롤 터치용 커스텀 함수성을 제공하려면 서브클래스에서 이를 덮어써야 합니다.
    • Sender 보낸이 - 터치된 MobileMenuObject 를 가리킵니다.
    • Touch[X/Y] 터치[X/Y] - 터치의 픽셀 단위 [가로/세로] 위치를 담습니다.
    • bCancel 취소? - 참이면 터치는 사용자가 아닌 시스템 이벤트와 같은 외부 요인에 의해 취소된 것입니다.

기본 버튼 예제

버튼에서 입력을 받아 어떤 동작을 취하게 하는 기본 예제를 만들어 보려면, 위에서 '콘트롤 만들기' 예제를 따 오시기 바랍니다.

class MobileMenuExample extends MobileMenuScene;

defaultproperties
{
   Left=0
   Top=0
   Width=1.0
   Height=180
   bRelativeWidth=true

   Begin Object Class=MobileMenuImage Name=Background
      Tag="Background"
      Left=0
      Top=0
      Width=1.0
      Height=1.0
      bRelativeWidth=true
      bRelativeHeight=true
      Image=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImageDrawStyle=IDS_Stretched
      ImageUVs=(bCustomCoords=true,U=0,V=30,UL=1024,VL=180)
   End Object
   MenuObjects.Add(Background)

   Begin Object Class=MobileMenuButton Name=ExploreButton
      Tag="EXPLORE"
      Left=0.35
      Top=0.35
      Width=140
      Height=24
      bRelativeLeft=true
      bRelativeTop=true
      TopLeeway=20
      Images(0)=Texture2D'CastleUI.menus.T_CastleMenu2'
      Images(1)=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImagesUVs(0)=(bCustomCoords=true,U=306,V=220,UL=310,VL=48)
      ImagesUVs(1)=(bCustomCoords=true,U=306,V=271,UL=310,VL=48)
   End Object
   MenuObjects.Add(ExploreButton)
}

버튼을 터치했을 때 뭔가 하게 만들려면, OnTouch() 이벤트에 버튼 눌림 처리 함수성을 추가시켜 덮어써 줘야 합니다. 먼저 (MobileMenuScene 클래스에서 복사할 수 있는) 함수 시그너처를 추가합니다.:

function OnTouch(MobileMenuObject Sender,float TouchX, float TouchY, bool bCancel)
{
}

다음으로 약간의 모난 경우를 처리해 줘야 합니다. Sender 가 비어 있거나 bCancel 파라미터가 설정된 경우, 함수는 아무 것도 하지 않고 반환해야 합니다.

if(Sender == none)
{
   return;
}

if(bCancel)
{
   return;
}

마지막으로, 버튼이 눌렸을 경우도 처리해 줘야 합니다. 이 예제에서는 단순히 메뉴 자체가 닫히도록 하는 버튼입니다.

if(Sender.Tag ~= "EXPLORE")
{
   InputOwner.CloseMenuScene(self);
}

먼저 SenderTag 를 검사하여 (~= 연산자로 대소문자 무관 검사) defaultproperties 안 버튼에 지정된 Tag 와 같은지 확인합니다. 검사를 통과하고 버튼이 콘트롤에 터치된 경우, CloseMenuScene() 함수가 Inputowner 상에서 호출되는데, 이는 로컬 플레이어의 경우 MobilePlayerInput 으로 여기에 메뉴 자체 로의 참조 self 를 전달합니다.

씬 클래스에 완전 통합된 OnTouch() 함수는:

class MobileMenuExample extends MobileMenuScene;

function OnTouch(MobileMenuObject Sender,float TouchX, float TouchY, bool bCancel)
{
   if(Sender == none)
   {
      return;
   }

   if(bCancel)
   {
      return;
   }

   if(Sender.Tag ~= "EXPLORE")
   {
      InputOwner.CloseMenuScene(self);
   }
}

defaultproperties
{
   Left=0
   Top=0
   Width=1.0
   Height=180
   bRelativeWidth=true

   Begin Object Class=MobileMenuImage Name=Background
      Tag="Background"
      Left=0
      Top=0
      Width=1.0
      Height=1.0
      bRelativeWidth=true
      bRelativeHeight=true
      Image=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImageDrawStyle=IDS_Stretched
      ImageUVs=(bCustomCoords=true,U=0,V=30,UL=1024,VL=180)
   End Object
   MenuObjects.Add(Background)

   Begin Object Class=MobileMenuButton Name=ExploreButton
      Tag="EXPLORE"
      Left=0.35
      Top=0.35
      Width=140
      Height=24
      bRelativeLeft=true
      bRelativeTop=true
      TopLeeway=20
      Images(0)=Texture2D'CastleUI.menus.T_CastleMenu2'
      Images(1)=Texture2D'CastleUI.menus.T_CastleMenu2'
      ImagesUVs(0)=(bCustomCoords=true,U=306,V=220,UL=310,VL=48)
      ImagesUVs(1)=(bCustomCoords=true,U=306,V=271,UL=310,VL=48)
   End Object
   MenuObjects.Add(ExploreButton)
}

이 메뉴 작동방식은 이와 같습니다:

메뉴 열림

basicinput_0.jpg

버튼 터치됨

basicinput_1.jpg

메뉴 닫힘

basicinput_2.jpg

커스텀 터치 인풋

OnSceneTouch 씬 터치시

씬은 OnSceneTouch() 이벤트 편을 통해 모든 터치 인풋 통지를 받습니다. 이를 통해 씬이 특정 콘트롤에서의 터치 이벤트를 처리할 수 있을 뿐만 아니라, 스와이프나 기타 제스처같은 커스텀 유형 인풋을 수행하기 위한 범용 입력도 처리할 수 있습니다.

  • OnSceneTouch [EventType] [TouchX] [TouchY] 씬 터치시 - 씬의 경계 내에 터치 이벤트가 발생했을 때 엔진이 호출하는 이벤트 토막입니다. 씬의 콘트롤에 꼭 직접 관계되지 않는 커스텀 터치 입력 처리 기능을 제공하려면 서브클래스에서 이를 덮어써야 합니다.
    • EventType 이벤트 유형 - 터치 이벤트의 EZoneTouchEvent 유형을 담습니다. 터치 이벤트 유형에 관련된 상세 정보는 Mobile Input System KR 페이지를 참고해 주시기 바랍니다.
    • Touch[X/Y] 터치[X/Y] - 터치의 픽셀 단위 [가로/세로] 위치를 담습니다.