Matt Doyle
09-21-2011, 03:26 PM
This is a step by step, high level explanation of how GFxUDKFrontEnd loads and displays each view of the menu which ships with UDK.
[Tested Working as of: July 2012 UDK] You may download a simplified version of the UDK Front End files --> HERE (http://dl.dropbox.com/u/39898937/UDK/FrontEnd_SimpleExample.zip) <--
This simplified version illustrates the code & assets needed for pushing & popping 2 views (Main Menu & Options) to a viewstack, using a menu manager. It contains custom files & assets (not covered below, but similar in execution).
NOTE: If you download and use the simplified version above, add the following two lines to [Engine.PackagesToForceCookPerMap] in DefaultEngine.ini.
.Map=SF-FrontEnd
.Package=SFSandbox
Files Involved
Unreal Script Files Involved
The Menu Manager - \Development\Src\UTGame\GFxUDKFrontEnd.uc
The Views - \Development\Src\UTGame\GFxUDKFrontEnd_MainMenu.uc , *_Multiplayer.uc, *_Settings.uc, etc.
Base class for Views - Development\Src\UTGame\GFxUDKFrontEnd_Screen.uc
Base View class - \Development\Src\UTGame\GFxUDKFrontEnd_View.uc
Flash Files Involved
The Manager - \UDKGame\Flash\UDKFrontEnd\udk_manager.fla
The Views - \UDKGame\Flash\UDKFrontEnd\udk_main_menu.fla, *_multiplayer.fla, *_settings.fla, etc.
All graphical assets pulled from this file - \UDKGame\Flash\UDKFrontEnd\udk_assets.fla
ActionScript Files Involved
The Views - \UDKGame\Flash\ActionScript\com\scaleform\udk\view s\MainMenuView.as, MultiplayerView.as, SettingsView.as, etc.
The Manager - \UDKGame\Flash\ActionScript\com\scaleform\udk\mana gers\MenuManager.as
Utlility for registering a document's class - \UDKGame\Flash\ActionScript\com\scaleform\udk\util s\UDKUtils.as
Other Files
\UDKGame\Config\DefaultUI.ini
\UDKGame\Content\Maps\UT3\UDKFrontEndMap.udk
\UDKGame\Flash\UDKFonts\fonts_en.fla
\UDKGame\Flash\UDKFonts\gfxfontlib.fla
Modifying and Reimporting the Front End Menu Files
If you make changes to any of the Flash files of the front end menu system, be very careful to follow the procedure below to ensure they continue to work properly once reimported into UDK.
First, Add this classpath to the ActionScript 2.0 Settings, directly above $(LocalData)/Classes and below the \Development\Flash\AS3\CLIK\ classpath: C:\UDK\UDK-2012-03\UDKGame\Flash\ActionScript\
Publish/compile these files into SWF files in this order:
\UDKGame\Flash\UDKFonts\fonts_en.fla
\UDKGame\Flash\UDKFonts\gfxfontlib.fla
Now, make your changes in the \UDKFrontEnd\udk_assets.fla file. For instance, to mofidy the main menu, make changes inside the main_menu movie clip found in the library panel of this file.
Save and compile the file.
Do the same for any other fla files you modified as well.
Now, reimport everything into UDK by adding the following line to a batch file (.bat), and executing the file:
C:\UDK\UDK-2012-03\Binaries\Win64\UDK.exe gfximport
Test your changes.
The Menu Manager
GFxUDKFrontEnd.uc is the master class (or manager) for the front end (menu). It extends GFxMoviePlayer, and makes use of the config file DefaultUI.ini. It is called in the startup level (UDKFrontEndMap) in Kismet via Open GFx Movie. The Movie loaded there is: UDKFrontEnd.udk_manager (package name.swf name), and the Movie Player Class is set to GFxUDKFrontEnd. Take Focus, Capture Input, and Display With Hud Off are all checked.
* GFxUDKFrontEnd’s SWF is also defined in the defaultproperties of GFxUDKFrontEnd.uc as: UDKFrontEnd.udk_manager
* On frame 1 of the actions layer, udk_manager.FLA/SWF is given the document class of: com.scaleform.udk.managers.MenuManager (MenuManager.as)
a. MenuManager.as initializes the _viewStack array & provides several functions for tweening (animating) the viewstack.
b. On the 'canvas' layer, udk_manager.FLA contains the empty movieClip: manager which is of type: manager. This movieClip will be used to hold the views.
GFxUDKFrontEnd.uc Variables
ViewInfo data structure
a. ViewName, SwfName, and DependantViews
b. These values will be populated by data in DefaultUI.ini
ViewData[] array of type ViewInfo
a. +ViewData lines defined in DefaultUI.ini
GFxUDKFrontEnd.uc Function Execution
1. Start() is executed
a. Calls ConfigFrontEnd()
2. ConfigFrontEnd() is executed
a. “_root” of udk_manager.fla is cached in RootMC
b. “manager” movie clip from udk_manager.fla is cached in ManagerMC
3. Start() calls LoadViews()
4. LoadViews() is executed
a. Calls LoadView() passing each element (each view) of the ViewData[] array
5. LoadView() is executed
a. A new empty movieclip is created inside ManagerMC with the name: SomeViewNameContainer (example: MainMenuContainer, MultiplayerContainer, HostGameContainer, etc.)
i. And this new movieclip is referenced by ViewContainer
b. A new empty movie clip is then created inside the ViewContainer with the name: SomeViewName.
i. This new movieclip is referenced by ViewLoader.
c. We get the SWFName and store at element 0 of the args[] array of asvals as a string.
d. We then invoke “loadMovie” (a standard Flash function in a GFxObject) on ViewLoader, passing it the SWFName via the args[] array.
i. This loads the actual SWF file for that view into the ViewLoader movie clip as a new movie clip.
ii. The SWF files sets their document class (example: com.scaleform.udk.views.MainMenuView (MainMenuView.as))
iii. The SWFs contain an empty movie clip of type container with the instance name: “container”
1. Inside “container” is another movie clip which is loaded via runtime sharing. “udk_main_menu.fla” for instance has the “main_menu” movie clip of type main_menu.
a. These movie clips have been imported into the SWF via runtime sharing from udk_assets.swf
b. UDK_assets.swf contains all the views in the library, and each view is setup to export for runtime sharing in the properties.
iv. The newly loaded SWF fires off a CLIK WidgetInitialized event with the ActionScript: if (enableInitCallback && _global.CLIK_loadCallback) { _global.CLIK_loadCallback(this._name, targetPath(this), this); }
e. Finally, we add the name of the view to the LoadedViews[] array.
6. WidgetInitialized() is executed for each loaded view as they are loaded.
a. Example: MainMenu
i. MainMenuView is created of type GFxUDKFrontEnd_MainMenu
ii. Calls ConfigureView()
iii. ConfigureView() is executed.
1. SetWidgetPathBinding() is called - this function sets it up so that all child widget's found in the view's path will send their initCallBack events to the view's WidgetInitialized() handler.
a. This requires using SubWidgetBindings.Add instead of the usual WidgetBindings.Add in the default properties when binding a widget.
iv. (MainMenuView ONLY) Calls ConfigureTargetView()
7. ConfigureTargetView() is executed (for the first view only – main menu)
a. This function first tests to see if the view is already on the stack or not.
b. Calls OnViewActivated() (found in GFxUDKFrontEnd_View.uc)
c. Calls OnTopMostView(), passing true.
i. OnTopMostView() plays the open animation & sets the escape key delegate.
d. Adds the view to the UnrealScript ViewStack[] array.
e. Calls PushView().
8. PushView() is executed.
a. Fires off the ActionScript function pushStandardView() in MenuManager.as, passing it the new view.
MenuManager.as Function Execution
1. pushStandardView() is executed.
a. Calls pushViewImpl()
2. pushViewImpl() is executed.
a. Tweens the new view into place.
b. Pushes the new view onto the _vewStack[] array in AS.
"Popping" a View
When a view is "popped" off the viewstack, as when pressing BACK to go from the Multiplayer screen to the Main Menu, the essential functions used are:
PopView()
PopViewStub()
Each Screen has a "Back" button. The Back button is bound in GFxUDKFrontEnd_Screen.uc in the defaultproperites:
defaultproperties
{
// General
SubWidgetBindings.Add((WidgetName="list",WidgetClass=class'GFxClikWidget'))
SubWidgetBindings.Add((WidgetName="back",WidgetClass=class'GFxClikWidget'))
AcceptButtonImage="pc_enter_png"
CancelButtonImage="pc_esc_png"
AcceptButtonHelpText="SELECT"
CancelButtonHelpText="BACK"
}
In the WidgetInitialized() handler of GFxUDKFrontEnd_Screen.uc, the Back button is told to listen for 'CLIK_press' events, and to execute Select_Back() on press.:
case ('back'):
BackBtn = GFxClikWidget(Widget.GetObject("btn", class'GFxClikWidget'));
BackBtn.SetString("label", "BACK");
BackBtn.AddEventListener('CLIK_press', Select_Back);
BackBtn.AddEventListener('CLIK_focusIn', FocusIn_BackButton);
bWasHandled = true;
break;
The event handler Select_Back() is found in GFxUDKFrontEnd_View. It fires off the function MoveBackImpl():
function Select_Back(GFxClikWidget.EventData ev)
{
MoveBackImpl();
}
MoveBackImpl() executes PopView() from the MenuManager (GFxUDKFrontEnd.uc)
function MoveBackImpl()
{
if (MenuManager != none)
{
PlayCloseAnimation();
MenuManager.PopView();
}
}
PopView() removes the current view from the ViewStack[] array.
ViewStack.Remove(ViewStack.Length-1, 1);
It then executes the OnTopMostView() function of the previous view (which is now the current view).
ViewStack[ViewStack.Length-1].OnTopMostView( false );
Last of all, it executes the PopViewStub() function as its return value.
PopViewStub() executes the popView() ActionScript function found in MenuManager.as
popView() then executes popViewImpl() which tweens the movie out.
[Tested Working as of: July 2012 UDK] You may download a simplified version of the UDK Front End files --> HERE (http://dl.dropbox.com/u/39898937/UDK/FrontEnd_SimpleExample.zip) <--
This simplified version illustrates the code & assets needed for pushing & popping 2 views (Main Menu & Options) to a viewstack, using a menu manager. It contains custom files & assets (not covered below, but similar in execution).
NOTE: If you download and use the simplified version above, add the following two lines to [Engine.PackagesToForceCookPerMap] in DefaultEngine.ini.
.Map=SF-FrontEnd
.Package=SFSandbox
Files Involved
Unreal Script Files Involved
The Menu Manager - \Development\Src\UTGame\GFxUDKFrontEnd.uc
The Views - \Development\Src\UTGame\GFxUDKFrontEnd_MainMenu.uc , *_Multiplayer.uc, *_Settings.uc, etc.
Base class for Views - Development\Src\UTGame\GFxUDKFrontEnd_Screen.uc
Base View class - \Development\Src\UTGame\GFxUDKFrontEnd_View.uc
Flash Files Involved
The Manager - \UDKGame\Flash\UDKFrontEnd\udk_manager.fla
The Views - \UDKGame\Flash\UDKFrontEnd\udk_main_menu.fla, *_multiplayer.fla, *_settings.fla, etc.
All graphical assets pulled from this file - \UDKGame\Flash\UDKFrontEnd\udk_assets.fla
ActionScript Files Involved
The Views - \UDKGame\Flash\ActionScript\com\scaleform\udk\view s\MainMenuView.as, MultiplayerView.as, SettingsView.as, etc.
The Manager - \UDKGame\Flash\ActionScript\com\scaleform\udk\mana gers\MenuManager.as
Utlility for registering a document's class - \UDKGame\Flash\ActionScript\com\scaleform\udk\util s\UDKUtils.as
Other Files
\UDKGame\Config\DefaultUI.ini
\UDKGame\Content\Maps\UT3\UDKFrontEndMap.udk
\UDKGame\Flash\UDKFonts\fonts_en.fla
\UDKGame\Flash\UDKFonts\gfxfontlib.fla
Modifying and Reimporting the Front End Menu Files
If you make changes to any of the Flash files of the front end menu system, be very careful to follow the procedure below to ensure they continue to work properly once reimported into UDK.
First, Add this classpath to the ActionScript 2.0 Settings, directly above $(LocalData)/Classes and below the \Development\Flash\AS3\CLIK\ classpath: C:\UDK\UDK-2012-03\UDKGame\Flash\ActionScript\
Publish/compile these files into SWF files in this order:
\UDKGame\Flash\UDKFonts\fonts_en.fla
\UDKGame\Flash\UDKFonts\gfxfontlib.fla
Now, make your changes in the \UDKFrontEnd\udk_assets.fla file. For instance, to mofidy the main menu, make changes inside the main_menu movie clip found in the library panel of this file.
Save and compile the file.
Do the same for any other fla files you modified as well.
Now, reimport everything into UDK by adding the following line to a batch file (.bat), and executing the file:
C:\UDK\UDK-2012-03\Binaries\Win64\UDK.exe gfximport
Test your changes.
The Menu Manager
GFxUDKFrontEnd.uc is the master class (or manager) for the front end (menu). It extends GFxMoviePlayer, and makes use of the config file DefaultUI.ini. It is called in the startup level (UDKFrontEndMap) in Kismet via Open GFx Movie. The Movie loaded there is: UDKFrontEnd.udk_manager (package name.swf name), and the Movie Player Class is set to GFxUDKFrontEnd. Take Focus, Capture Input, and Display With Hud Off are all checked.
* GFxUDKFrontEnd’s SWF is also defined in the defaultproperties of GFxUDKFrontEnd.uc as: UDKFrontEnd.udk_manager
* On frame 1 of the actions layer, udk_manager.FLA/SWF is given the document class of: com.scaleform.udk.managers.MenuManager (MenuManager.as)
a. MenuManager.as initializes the _viewStack array & provides several functions for tweening (animating) the viewstack.
b. On the 'canvas' layer, udk_manager.FLA contains the empty movieClip: manager which is of type: manager. This movieClip will be used to hold the views.
GFxUDKFrontEnd.uc Variables
ViewInfo data structure
a. ViewName, SwfName, and DependantViews
b. These values will be populated by data in DefaultUI.ini
ViewData[] array of type ViewInfo
a. +ViewData lines defined in DefaultUI.ini
GFxUDKFrontEnd.uc Function Execution
1. Start() is executed
a. Calls ConfigFrontEnd()
2. ConfigFrontEnd() is executed
a. “_root” of udk_manager.fla is cached in RootMC
b. “manager” movie clip from udk_manager.fla is cached in ManagerMC
3. Start() calls LoadViews()
4. LoadViews() is executed
a. Calls LoadView() passing each element (each view) of the ViewData[] array
5. LoadView() is executed
a. A new empty movieclip is created inside ManagerMC with the name: SomeViewNameContainer (example: MainMenuContainer, MultiplayerContainer, HostGameContainer, etc.)
i. And this new movieclip is referenced by ViewContainer
b. A new empty movie clip is then created inside the ViewContainer with the name: SomeViewName.
i. This new movieclip is referenced by ViewLoader.
c. We get the SWFName and store at element 0 of the args[] array of asvals as a string.
d. We then invoke “loadMovie” (a standard Flash function in a GFxObject) on ViewLoader, passing it the SWFName via the args[] array.
i. This loads the actual SWF file for that view into the ViewLoader movie clip as a new movie clip.
ii. The SWF files sets their document class (example: com.scaleform.udk.views.MainMenuView (MainMenuView.as))
iii. The SWFs contain an empty movie clip of type container with the instance name: “container”
1. Inside “container” is another movie clip which is loaded via runtime sharing. “udk_main_menu.fla” for instance has the “main_menu” movie clip of type main_menu.
a. These movie clips have been imported into the SWF via runtime sharing from udk_assets.swf
b. UDK_assets.swf contains all the views in the library, and each view is setup to export for runtime sharing in the properties.
iv. The newly loaded SWF fires off a CLIK WidgetInitialized event with the ActionScript: if (enableInitCallback && _global.CLIK_loadCallback) { _global.CLIK_loadCallback(this._name, targetPath(this), this); }
e. Finally, we add the name of the view to the LoadedViews[] array.
6. WidgetInitialized() is executed for each loaded view as they are loaded.
a. Example: MainMenu
i. MainMenuView is created of type GFxUDKFrontEnd_MainMenu
ii. Calls ConfigureView()
iii. ConfigureView() is executed.
1. SetWidgetPathBinding() is called - this function sets it up so that all child widget's found in the view's path will send their initCallBack events to the view's WidgetInitialized() handler.
a. This requires using SubWidgetBindings.Add instead of the usual WidgetBindings.Add in the default properties when binding a widget.
iv. (MainMenuView ONLY) Calls ConfigureTargetView()
7. ConfigureTargetView() is executed (for the first view only – main menu)
a. This function first tests to see if the view is already on the stack or not.
b. Calls OnViewActivated() (found in GFxUDKFrontEnd_View.uc)
c. Calls OnTopMostView(), passing true.
i. OnTopMostView() plays the open animation & sets the escape key delegate.
d. Adds the view to the UnrealScript ViewStack[] array.
e. Calls PushView().
8. PushView() is executed.
a. Fires off the ActionScript function pushStandardView() in MenuManager.as, passing it the new view.
MenuManager.as Function Execution
1. pushStandardView() is executed.
a. Calls pushViewImpl()
2. pushViewImpl() is executed.
a. Tweens the new view into place.
b. Pushes the new view onto the _vewStack[] array in AS.
"Popping" a View
When a view is "popped" off the viewstack, as when pressing BACK to go from the Multiplayer screen to the Main Menu, the essential functions used are:
PopView()
PopViewStub()
Each Screen has a "Back" button. The Back button is bound in GFxUDKFrontEnd_Screen.uc in the defaultproperites:
defaultproperties
{
// General
SubWidgetBindings.Add((WidgetName="list",WidgetClass=class'GFxClikWidget'))
SubWidgetBindings.Add((WidgetName="back",WidgetClass=class'GFxClikWidget'))
AcceptButtonImage="pc_enter_png"
CancelButtonImage="pc_esc_png"
AcceptButtonHelpText="SELECT"
CancelButtonHelpText="BACK"
}
In the WidgetInitialized() handler of GFxUDKFrontEnd_Screen.uc, the Back button is told to listen for 'CLIK_press' events, and to execute Select_Back() on press.:
case ('back'):
BackBtn = GFxClikWidget(Widget.GetObject("btn", class'GFxClikWidget'));
BackBtn.SetString("label", "BACK");
BackBtn.AddEventListener('CLIK_press', Select_Back);
BackBtn.AddEventListener('CLIK_focusIn', FocusIn_BackButton);
bWasHandled = true;
break;
The event handler Select_Back() is found in GFxUDKFrontEnd_View. It fires off the function MoveBackImpl():
function Select_Back(GFxClikWidget.EventData ev)
{
MoveBackImpl();
}
MoveBackImpl() executes PopView() from the MenuManager (GFxUDKFrontEnd.uc)
function MoveBackImpl()
{
if (MenuManager != none)
{
PlayCloseAnimation();
MenuManager.PopView();
}
}
PopView() removes the current view from the ViewStack[] array.
ViewStack.Remove(ViewStack.Length-1, 1);
It then executes the OnTopMostView() function of the previous view (which is now the current view).
ViewStack[ViewStack.Length-1].OnTopMostView( false );
Last of all, it executes the PopViewStub() function as its return value.
PopViewStub() executes the popView() ActionScript function found in MenuManager.as
popView() then executes popViewImpl() which tweens the movie out.