UDN
Search public documentation:

GFxCreateCursorKR
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 > Scaleform GFx > 마우스 커서 만드는 법

마우스 커서 만드는 법


문서 변경내역: James Tan 작성. 홍성진 번역.

개요


이 중급 튜토리얼은 기존의 HUD 에 토글 가능한 마우스 커서를 추가하는 법에 대한 것입니다. 마우스 커서는 플래시 파일의 스테이지에는 존재하지 않으며, 라이브러리에만 있습니다. 사용자가 키보드의 왼쪽 Shift 키를 계속 누르고 있으면, UnrealScript 가 실행시간에 인스턴스를 만들어 _root 플래시 타임라인에 붙입니다.

ALERT! 주: 이 방법을 사용하면, 버튼, 드롭다운, 체크박스 등 (마우스 커서를 제외한) 모든 UI 콘텐츠를 _root 에 있는 컨테이너 무비 클립 안에 넣어주는 것이 가장 좋습니다. 마우스 커서 역시 _root 에 있을 것입니다. 그러면 (드롭다운 메뉴 위젯에서 찾을 수 있는 것과 같은) 팝업 UI 엘리먼트가 열린다 할지라도 마우스 커서를 확실히 맨위에 오도록 할 수 있는 것입니다. 이 팝업 엘리먼트는 보통 실행시간에 동적으로 생성될 때 다른 것보다 위에 오도록 설정되게 마련이거든요. 컨테이너 무비 클립 안에 있지 않은 다음에야, 팝업 위젯이 마우스 커서 위로 떠 버릴 것입니다.

플래시


  • HUD FLA 파일을 열고, 스테이지에 새로운 마우스 커서 그래픽을 비트맵 이미지로든 플래시 드로잉 툴을 사용해서든 만듭니다. 대부분의 커서가 그렇듯 뾰족한 부분이 좌상단 구석을 가리키도록 하는 것, 잊지 마시구요.
  • 이제 커서 그래픽을 선택하고 우클릭한 뒤 'Convert to Symbol', 심볼로 변환합니다.
  • Name 필드에 MouseContainer 라고 입력합니다.
  • Type 은 Movie Clip 이어야 하겠고요.
  • Registration 은 top-left 로 설정해 줍니다.
  • Export for ActionScript 와 Export in frame 1 을 켭니다.
  • Identifier 에 MouseContainer 라 입력합니다.
  • OK 를 누릅니다.
  • 이제 스테이지의 커서에 더블클릭하여 MouseContainer 무비 클립에 들어갑니다.
  • 그래픽을 다시 선택하고 우클릭, 'Convert to Symbol' 을 다시 합니다.
  • Name 은 MouseImage 입니다.
  • Type 은 다시 Movie Clip 이겠고요.
  • Registration 역시도 top-left 입니다.
  • OK 누르고요.
  • 스테이지의 커서 무비 클립을 선택한 다음 인스턴스 이름을 mouseCursor_mc 라고 짓습니다.
  • 이제 계층구조는 다음과 같을 것입니다:
    • MouseContainer 무비클립 (인스턴스 이름 없음)
      • MouseImage 무비클립 (인스턴스 이름: mouseCursor_mc)
        • 마우스 커서 비트맵 이미지
  • 이 무비클립(mouseCursor_mc)에 드롭 섀도우같은 필터를 아무거나 추가합니다.
  • 이제 mouseCursor_mc 선택을 취소하고, (MouseContainer 안에 있는) 타임라인에 레이어를 새로 추가하고, actions 라 부릅니다.
  • actions 레이어의 프레임 1 에 이 코드를 입력합니다:

ActionScript
import flash.external.ExternalInterface;

Mouse.hide();

var mouseListener:Object = new Object();

mouseListener.onMouseMove = function ()
{
  mouseCursor_mc._x = _root._xmouse;
  mouseCursor_mc._y = _root._ymouse;

  ExternalInterface.call("UpdateMousePosition", _root._xmouse, _root._ymouse);

  updateAfterEvent();
};

Mouse.addListener(mouseListener);

  • 이제 플래시 파일의 _root 타임라인으로 돌아가서, 스테이지에서 커서 무비 클립(MouseContainer)을 지웁니다. 걱정 마세요. 아직 라이브러리에 남아 있으니까요. : 라이브러리에는 무비클립이 둘 있을 것입니다. 바로 MouseContainer 와 MouseImage 에다 마우스 커서 비트맵 이미지를 더해서요.
  • 저장하고 퍼블리시환 뒤 수정된 HUD 파일을 UDK 로 임포트합니다.

UnrealScript - HUD 클래스 변경 (GFxMoviePlayer 확장)


먼저 (GFxMoviePlayer 를 확장하는) HUD 클래스에 이 변수들을 추가합니다:

// 표준 플래시 오브젝트
var GFxObject RootMC, MouseContainer, MouseCursor;

var array<ASValue> args;

이 코드를 Start() 나 Init() 함수에 추가합니다.

RootMC = GetVariableObject("_root");
AddFocusIgnoreKey('LeftShift'); // HUD 더러 왼쪽 Shift 키입력을 무시하라 이릅니다.

Add these functions to your class:

event UpdateMousePosition(float X, float Y)
{
  local MouseInterfacePlayerInput MouseInterfacePlayerInput;

  MouseInterfacePlayerInput = MouseInterfacePlayerInput(GetPC().PlayerInput);
  if (MouseInterfacePlayerInput != None)
  {
    MouseInterfacePlayerInput.SetMousePosition(X, Y);
  }
}

/** 마우스 커서를 껐다/켰다 토글합니다. */
function ToggleCursor(bool showCursor, float mx, float my)
{
  if (showCursor)
  {
    MouseContainer = CreateMouseCursor();
    MouseCursor = MouseContainer.GetObject("my_cursor");
    MouseCursor.SetPosition(mx,my);
    MouseContainer.SetBool("topmostLevel", true);
  }
  else
  {
    MouseContainer.Invoke("removeMovieClip", args);
    MouseContainer = none;
  }

  bIgnoreMouseInput = !showCursor;
}

function GFxObject CreateMouseCursor()
{
  return RootMC.AttachMovie("MouseContainer", "MouseCursor");
}

CreateMouseCursor 함수는 Identifier(식별자)가 MouseContainer 인 플래시 내 무비 클립을 _root 타임라인 (Stage) 에 붙이고(attach), 그 인스턴스 이름은 MouseCursor 라 합니다.

defaultproperties 에는 꼭 다음 줄이 들어가야 합니다:

defaultproperties
{
  bIgnoreMouseInput = true
}

UnrealScript - HUD Wrapper 클래스 변경


먼저 이 변수들을 HUD Wrapper (위의 HUD 클래스의 인스턴스를 만드는) 클래스에 추가합니다:

var GFxObject HudMovieSize;
var MouseInterfacePlayerInput MouseInterfacePlayerInput;
var float MouseX, MouseY;

다음으로 PostBeginPlay() 함수에 (빨간) 코드 줄을 추가합니다:

simulated function PostBeginPlay()
{
  Super.PostBeginPlay();

  // HUD 인스턴스화 코드를 여기에...

  // Stage.originalRect 에는 SWF 파일의 원래 폭과 높이가 들어 있습니다.
  // HudMovie 를 HUD 인스턴스 이름으로 대체
  HudMovieSize = HudMovie.GetVariableObject("Stage.originalRect");

  MouseInterfacePlayerInput = MouseInterfacePlayerInput(PlayerOwner.PlayerInput);
}

다음으로 이 함수, 사용자가 왼쪽 Shift 키를 누르면 발동(실행)될 함수를 추가합니다. 이 함수는 HUD 클래스에서 ToggleCursor() 함수를 호출한 다음, 왼쪽 Shift 키가 눌려 있으면 참을 전달하고, 눌려 있지 않으면 거짓을 전달합니다. 마우스의 X & Y 위치 역시도 전달합니다.

exec function SetShowCursor(bool showCursor)
{
  // HudMovie 를 HUD 인스턴스 이름으로 대체합니다.
  HudMovie.ToggleCursor(showCursor, MouseX, MouseY);
}

이제 PostRender() 이벤트 함수, HudMovie.TickHud(0) 호출 바로 위에 다음 코드줄을 추가합니다. 이 코드 두 줄은 마우스 커서의 X & Y 위치를 구하는 데 사용됩니다:

event PostRender()
{
  super.PostRender();

  MouseX = MouseInterfacePlayerInput.MousePosition.X;
  MouseY = MouseInterfacePlayerInput.MousePosition.Y;

  // Tick HUD
  if (HudMovie != none)
  {
    HudMovie.TickHud(0);
  }
}

UnrealScript - MouseInterfacePlayerInput 클래스


이 클래스를 새로 만들어 MouseInterfacePlayerInput.uc 로 저장합니다. SFHudWrapper 의 인스턴스 전부를 HUD Wrapper 클래스 이름으로 대체하는 것, 잊지 마시구요:

class MouseInterfacePlayerInput extends PlayerInput;

// 보관된 마우스 위치. PrivateWrite 로 설정하면 다른 클래스가 변경은 못하지만 접근은 가능합니다.
var PrivateWrite IntPoint MousePosition;
var SFHudWrapper SFHudWrapper;
var float HudX, HudY;

event PlayerInput(float DeltaTime)
{
  GetHudSize();

  if (myHUD != None)
  {
    // 마우스 위치에 aMouseX 를 더하고, 뷰포트 폭 범위로 제한시킵니다.
    MousePosition.X = Clamp(MousePosition.X + aMouseX, 0, HudX);
    // 마우스 위치에 aMouseY 를 더하고, 뷰포트 높이 범위로 제한시킵니다.
    MousePosition.Y = Clamp(MousePosition.Y - aMouseY, 0, HudY);
  }

  Super.PlayerInput(DeltaTime);
}

// HUD SWF 의 원래 폭과 높이를 구해 그 변수들을 HudX 와 HudY 에 보관하는 함수입니다.
function GetHudSize()
{
  // 먼저 HUD Wrapper 로의 리퍼런스를 보관한 다음 HUD 의 해상도를 구합니다.
  SFHudWrapper = SFHudWrapper(myHUD);
  HudX = SFHudWrapper.HudMovieSize.GetFloat("width");
  HudY = SFHudWrapper.HudMovieSize.GetFloat("height");
}

function SetMousePosition(int X, int Y)
{
  GetHudSize();

  if (MyHUD != None)
  {
    MousePosition.X = Clamp(X, 0, HudX);
    MousePosition.Y = Clamp(Y, 0, HudY);
  }
}

defaultproperties
{
}

UnrealScript - PlayerController 클래스 변경


PlayerController 클래스의 defaultproperties 에 다음 줄을 추가합니다:

defaultproperties
{
  InputClass=class'MouseInterfacePlayerInput'
}

환경설정 파일

그런 다음 DefaultInput.ini 파일에 다음 줄을 추가합니다:

.Bindings=(Name="LeftShift",Command="SetShowCursor true | Onrelease SetShowCursor false")

  • 저장하고 스크립트를 컴파일합니다.
  • 게임을 실행시켜 새로운 커서를 테스트합니다!