UDN
Search public documentation:

GFxCreateCursor
日本語訳
中国翻译
한국어

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 Home > User Interfaces & HUDs > Scaleform GFx > How to create a mouse cursor

How to create a mouse cursor


Overview


This intermediate level tutorial will explain how to add a toggle-able mouse cursor to an already existing HUD. The mouse cursor will not exist on the stage of the Flash file, but only in the library. It will be instantiated and attached to the _root Flash timeline at runtime by UnrealScript when the user presses and holds the Left Shift key on the keyboard.

ALERT! Note: Using this method, it is best to place all your UI content such as buttons, dropdowns, checkboxes, etc. (with the exception of the mouse cursor) inside a container movie clip that lives at _root. The mouse cursor will also live at _root. This will ensure the mouse is always on top, even when a popup UI element opens (such as that found in a drop down menu widget). These popup elements normally set themselves above everything else when they are created dynamically at runtime. Without being inside a container movie clip, the popup widget would appear above the mouse cursor.

Flash


  • Open your HUD FLA file, and create a new mouse cursor graphic on the stage, either with a bitmap image or using Flash drawing tools. Be sure the tip is pointing to the top-left corner, like most cursors.
  • Now Select the cursor graphic, right click, and choose 'Convert to Symbol'.
  • In the Name field, enter MouseContainer.
  • Type should be Movie Clip.
  • Registration should be set to top-left.
  • Enable Export for ActionScript and Export in frame 1.
  • In the Identifier field, enter MouseContainer.
  • Press OK.
  • Now, double click the cursor on stage to enter the MouseContainer movie clip.
  • Select the graphic again, right click, and choose 'Convert to Symbol' again.
  • Name it MouseImage
  • Type should again be Movie Clip.
  • Registration should again be top-left.
  • Press OK.
  • Select the cursor movie clip on stage, and give it an instance name of mouseCursor_mc.
  • You should now have the following hierarchy:
    • MouseContainer movieclip (no instance name)
      • MouseImage movieclip (instance name: mouseCursor_mc)
        • Mouse cursor bitmap image
  • Add any filters you like to this movie clip (mouseCursor_mc), such as a drop shadow filter.
  • Now, unselect mouseCursor_mc, add a new layer to the timeline (the timeline inside MouseContainer), and call it actions.
  • On frame 1 of the actions layer enter this code:

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);

  • Now return to the _root timeline of your Flash file, and delete the cursor movie clip (MouseContainer) form the stage. Don't worry, it still exists in the library. NOTE: You should have two movie clips in the library: MouseContainer & MouseImage, plus the mouse cursor bitmap image.
  • Save, Publish, and Import your modified HUD file into UDK.

UnrealScript - HUD Class Changes (extends GFxMoviePlayer)


First, add these vars to your HUD class (which extend GFxMoviePlayer):

// Standard Flash Objects
var GFxObject RootMC, MouseContainer, MouseCursor;

var array<ASValue> args;

Add this code to your Start() or Init() function.

RootMC = GetVariableObject("_root");
AddFocusIgnoreKey('LeftShift'); // Tells HUD to ignore Left Shift keyboard presses

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);
  }
}

/** Toggles mouse cursor on/off */
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");
}

The CreateMouseCursor function attaches the Movie Clip in Flash that has the Identifier of MouseContainer to the _root timeline (the Stage), and gives it an instance name of MouseCursor.

In the defaultproperties, be sure to include:

defaultproperties
{
  bIgnoreMouseInput = true
}

UnrealScript - HUD Wrapper Class Changes


First, add these variables to your HUD Wrapper class (the class that instantiates the HUD class above):

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

Next, add this line of code (in red) to your PostBeginPlay() function:

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

  // Your HUD instantiation code here...

  // Stage.originalRect contains the original width and height of the SWF file.
  // Replace HudMovie with the name of your instantiated HUD.
  HudMovieSize = HudMovie.GetVariableObject("Stage.originalRect");

  MouseInterfacePlayerInput = MouseInterfacePlayerInput(PlayerOwner.PlayerInput);
}

Next, add this function, which will be fired off (executed) when the user presses the Left Shift key. This function calls the ToggleCursor() function in the HUD class, and passes it true if the left shift key is pressed down, or false if it is released. It also passes the X & Y position of the mouse.

exec function SetShowCursor(bool showCursor)
{
  // Replace HudMovie with the name of your instantiated HUD.
  HudMovie.ToggleCursor(showCursor, MouseX, MouseY);
}

Now, add these lines of code to the PostRender() event function, just above the HudMovie.TickHud(0) call. These two lines of code are used to get the current X & Y position of the mouse cursor.:

event PostRender()
{
  super.PostRender();

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

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

UnrealScript - MouseInterfacePlayerInput Class


Create this new class and save it as MouseInterfacePlayerInput.uc. Be sure to replace all instances of SFHudWrapper with the name of your HUD Wrapper class:

class MouseInterfacePlayerInput extends PlayerInput;

// Stored mouse position. Set to private write as we don't want other classes to modify it, but still allow other classes to access it.
var PrivateWrite IntPoint MousePosition;
var SFHudWrapper SFHudWrapper;
var float HudX, HudY;

event PlayerInput(float DeltaTime)
{
  GetHudSize();

  if (myHUD != None)
  {
    // Add the aMouseX to the mouse position and clamp it within the viewport width
    MousePosition.X = Clamp(MousePosition.X + aMouseX, 0, HudX);
    // Add the aMouseY to the mouse position and clamp it within the viewport height
    MousePosition.Y = Clamp(MousePosition.Y - aMouseY, 0, HudY);
  }

  Super.PlayerInput(DeltaTime);
}

// This function gets the original width and height of the HUD SWF and stores those values in HudX and HudY.
function GetHudSize()
{
  // First store a reference to our HUD Wrapper and get the resolution of the 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 Class Changes


Add this line to the defaultproperties of your PlayerController class:

defaultproperties
{
  InputClass=class'MouseInterfacePlayerInput'
}

Config Files

Then, add this line to your DefaultInput.ini file: Code:

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

  • Save and compile scripts.
  • Test your new cursor by running the game!