UDN
Search public documentation:

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

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 > Scaleform GFx Quick Start

Scaleform GFx Quick Start


Overview


Getting your first menu or HUD created with Scaleform set up and working inside of Unreal Engine 3 can seem a daunting task. However, the process is pretty straightforward and painless. You do need Adobe Flash professional (or an equivalent) and need to know how to use it as we will not be going in-depth into how to set up every element inside Flash. The goal here is to hit all the major points necessary to get a Scaleform UI up and running inside Unreal Engine 3, not how to use Scaleform or Flash itself.

This document walks you through the creation of a simple menu (shown below) that is used to allow the player to enter some profile information about themselves, which will then be used to display a welcome message. Again, the point of this is simply to show you how to quickly get a working Scaleform UI into Unreal.

quickstart.jpg

Setting up the Scene


The scene is set up entirely inside of Flash, which provides a fairly easy to use interface for placing, modifying, and animating elements. We will not go into setting up each element of the scene step by step, but we will overview how the scene is organized. You can use the provided Flash file (download below) to follow along or use the information to create your own example. For more detailed documentation on working with Scaleform GFx in general, especially CLIK components, see the official Scaleform Documentation site.

Example Files
UI_QuickStart - Part 1
UI_QuickStart - Part 2
UI_QuickStart - Part 3
UI_QuickStart - Part 4
UI_QuickStart AS3 version (part 1 of 2)
UI_QuickStart AS3 version (part 2 of 2)

The scene consists of a background image, a label that displays a message, some fields for entering/displaying data, and two buttons to save the information or close the menu.

quickstart_scene.jpg

Animation

Each element besides the background image has been animated so that the elements move in from off-screen when the menu is opened. This isn't necessary, obviously; it's just to show an example of how animation is handled.

Instance Names

The most important thing to keep in mind is that any object you want to be able to access inside of UnrealScript should have its InstanceName set to something unique. This is how elements inside the scene are identified and allows you to get references to the objects. In the example, every element has its InstanceName set even though not all of them are things we will need access to later on, most notably the three labels that go with the text input components. For our purposes, access to these static labels is not needed; however, if you were localizing the text in your menus, you would indeed want to be able to access those elements.

instance_name.jpg

enableInitCallback

In order to have UnrealScript notified of a CLIK widget, the enableInitCallback property must be enabled on the CLIK widget inside of Flash. Any widgets you need access to inside of UnrealScript, should enable this property so that they get a WidgetInitialzed callback. This property is enabled by default, but should be disabled for any objects UnrealScript does not need to be aware of.

Cursor

Getting a cursor to display in a Scaleform UI is extremely simple. Add a movie clip to the scene that uses the cursor graphic and then add some ActionScript to it that sets the position of the cursor movie clip to the location of the mouse each update.

The cursor movieclip is created by importing the cursor graphic to the stage and converting it to a MovieClip symbol. This is then placed in a layer named Cursor that is just below the Actions layer, but above all other layers.

To add the ActionScript:

  1. Select the cursor movieclip and press F9 to open the ActionScript editor.
  2. Add the code below:
    Cursor ActionScript
       onClipEvent(enterFrame)
       {
             _X = _root._xmouse;
             _y = _root._ymouse;
       }
       

Images

Images used in your scene inside of Flash can be automatically imported with the scene, though they need to be set up properly to avoid any issues.

To prepare images for import:

  1. Select the image in the Library panel, right-click on it, and choose Properties.
    image_properties_menu.jpg
  2. In the Bitmap properties dialog, check Allow Smoothing and set Compression to Lossless (PNG/GIF).
    image_properties.jpg
  3. Click the advanced_button.jpg to display the advanced properties.
  4. In the Linkage section, enable Export for ActionScript and in the Identifier field, remove the file extension from the name of the image (including the period).
    image_linkage.jpg
  5. Click the ok_button.jpg button to save the changes.
  6. Finally, the original source image files should be placed in a folder with the same name as the SWF file (in the same directory as the SWF file).
    folder_images.jpg

Importing the Scene


Once the scene is set up in Flash, it needs to be transferred to Unreal so it can be used in-game. The first step is to publish the scene from within Flash to a .swf file. This happens automatically when you preview the scene using the Scaleform Launcher, but you can also publish it manually from the File menu by choosing File > Publish or by pressing Shift + F12.

publish_menu.jpg

The published .swf file should be located inside the [GameName]\Flash directory within a folder with the name of the package you would like the .swf imported into in Unreal. This folder corresponds directly to the package the .swf will be imported into and cannot be changed at import time. You can optionally have subfolders within this package folder that represent groups within the package.

folder_package.jpg

The easiest way to ensure the published .swf ends up in the correct location is simply to save the actual Flash file (.fla) to the desired location initially. The published file will be placed alongside it by default.

After the scene has been published, you can import it into Unreal through the Content Browser inside of UnrealEd or by using the GFXIMPORT commandlet. For this example, importing through the Content Browser will work fine.

  1. Open Unreal Editor, go to the Content Browser, and click the import_button.jpg button.
  2. Change the file type filter on the file browser that appears to SWF Movie (.swf) and navigate to the location of your published .swf file.
  3. Select the file and click the open_button.jpg button.
  4. In the Import dialog, the Package, Group, and Name fields will all be filled in and grayed out.
    import_dialog.jpg
    The default settings should work fine here. Click the ok_button.jpg button to import the scene.
  5. Once the import process is finished, the SWF and any images it contained should all be visible in the Content Browser.
    import_success.jpg

Hooking up the Scene


The UnrealScript class below is what drives our Scaleform UI example. The GFxMoviePlayer class is the base class for all Scaleform UIs. It is associated with a SWF via the Movie property, which it can then receive events from and pass commands to as well as accessing elements within the associated UI.

Please see Custom UnrealScript Projects for information on how to add a new UnrealScript project if you are just starting out.

The basic process that occurs is:

  • The movie player starts the movie - Start()
  • The movie player is initialized - Advance()
    • WidgetInitialized called for all elements that have enableInitCallback enabled
    • References are saved to needed widgets - any object in the scene we need to access should have a reference saved
    • Delegates are assigned for click events on buttons - Widget bindings are used so the Widget passed to WidgetInitialized for the buttons is a GFxCLICKWidget which can have event listeners added
  • Delegates are called when buttons are clicked
    • SaveButton - Message changes using player entered info
    • ExitButton - The UI is closed

UIScene_Profile.uc
class UIScene_Profile extends GFxMoviePlayer;

/** Reference to the label used to display the message on the UI */
var GFxObject MessageLabel;

/** Reference to the text field used to enter the player's name */
var GFxObject PlayerText;

/** Reference to the text field used to enter the player's title */
var GFxObject TitleText;

/** Reference to the text field used to enter the player's clan */
var GFxObject ClanText;

/** Reference to the button used to save the profile info - must add a widget binding since we expect a GFxCLIKWidget */
var GFxCLIKWidget SaveButton;

/** Reference to the button used to close the UI - must add a widget binding since we expect a GFxCLIKWidget */
var GFxCLIKWidget ExitButton;

// Called when the UI is opened to start the movie
function bool Start(optional bool StartPaused = false)
{
	// Start playing the movie
    Super.Start();

	// Initialize all objects in the movie
    Advance(0);

    return true;
}

// Callback automatically called for each object in the movie with enableInitCallback enabled
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
{
    // Determine which widget is being initialized and handle it accordingly
    switch(Widgetname)
    {
        case 'messageLabel':
        	// Save reference to the label that displays the message to the player
            MessageLabel = Widget;
            break;
        case 'playerText':
        	// Save reference to the text field for the player's name
            PlayerText = Widget;
            break;
        case 'titleText':
        	// Save reference to the text field for the player's title
            TitleText = Widget;
            break;
        case 'clanText':
        	// Save reference to the text field for the player's clan
            ClanText = Widget;
            break;
        case 'saveButton':
        	// Save reference to the button that saves the profile info
		// the Widget is cast to a GFxCLIKWidget to allow for event listeners - see WidgetBindings
            SaveButton = GFxCLIKWidget(Widget);
            // Add a delegate for when this button is clicked
            SaveButton.AddEventListener('CLIK_click', SavePlayerData);
            break;
        case 'exitButton':
        	// Save reference to the button that closes the UI
		// the Widget is cast to a GFxCLIKWidget to allow for event listeners - see WidgetBindings
            ExitButton = GFxCLIKWidget(Widget);
            // Add a delegate for when this button is clicked
            ExitButton.AddEventListener('CLIK_click', CloseMovie);
            break;
        default:
        	// Pass on if not a widget we are looking for
            return Super.WidgetInitialized(Widgetname, WidgetPath, Widget);
    }
    
    return false;
}

// Delegate added to change the message using the data entered
//In a real game situation, the data would be saved somewhere
function SavePlayerData(EventData data)
{
    // Only on left mouse button
    if(data.mouseIndex == 0)
    {
    	// Set the text property of the message label using the profile info entered
        MessageLabel.SetString("text", "Welcome,"@PlayerText.GetString("text")@"("$TitleText.GetString("text")@"in"@ClanText.GetString("text")$")");
    }
}

// Delegate added to close the movie
function CloseMovie(EventData data)
{
    // Only on left mouse button
    if(data.mouseIndex == 0)
    {
    	// Close the UI
        Close();
    }
}

defaultproperties
{
    // The imported SWF to use
	MovieInfo=SwfMovie'UDNHud.UI_QuickStart'

    // Set widget bindings so the Widget passed to
    // WidgetInitialized for the buttons is a GFxCLICKWidget
    WidgetBindings.Add((WidgetName="saveButton",WidgetClass=class'GFxCLIKWidget'))
    WidgetBindings.Add((WidgetName="exitButton",WidgetClass=class'GFxCLIKWidget'))

    // Set properties for the movie
    // TimingMode=TM_Real makes the menu run while the game is paused
    bDisplayWithHudOff=TRUE
    TimingMode=TM_Real
	bPauseGameWhileActive=TRUE
	bCaptureInput=true
}

Testing the Scene


It is time to test out the scene inside of the game to make sure it is working as expected. This is pretty simple to do. All you need is a map to run and a little Kismet to open the movie when the map loads. Of course, how and when you load any UI is completely dependent on the type of UI it is. A HUD would be handled through UnrealScript so it is always loaded. A main menu can simply be loaded through Kismet when the map loads as described previously. or, an in-game menu can be loaded using either method. For testing, the Kismet method is probably easiest though.

To open a Scaleform movie in Kismet:

  1. Add a Level Loaded (New Event > Level Loaded) event and a Open GFx Movie action (New Action > GFx UI > Open GFx Movie).
  2. Connect the Beginning of Level output of the Level Loaded event to the In input of the Open GFx Movie action.
  3. Select the imported SWF in the Content browser and in the Open GFx Movie action's properties press the use_selected_button.jpg button for the Movie property to assign the SWF.
  4. Set the Movie Player Class to the class from the previous section, UIScene_Profile in this case. This is the class that will drive the movie assigned in the previous step.
  5. Enable the Take Focus and Capture Input properties (assuming this is a menu and not a HUD) so the menu will be focused and accepting input.

The completed setup should look like this:

kismet_setup.jpg

Now, play the map using the pie_button.jpg button and the Scaleform UI should show up.

quickstart_load.jpg

The cursor should move as you move the mouse and the two button should cause the appropriate actions to occur: Changing the message or closing the UI.

quickstart.jpg