Tutorial: multi-language, multi-font Scaleform buttons and button bars, text and font set at runtime

As far as I know, there’s only one other person deep into Scaleform UI for UDK/UE3, so this post probably won’t be useful for too many people. But just in case anyone else ever wants to create a single UI for every language, this is how to do it. We’re going to use the Button.textField.htmlText property to set the text in all of our buttons.

First off, embed your fonts in your font library and import them into your fla as usual:

Now, just to experiment, you can drop a CLIK button (copy from CLIK_Components_AS3.fla and paste into your fla). Name it button. Then somewhere on the timeline, add this code:

button.textField.htmlText = "<font size=\"20\" face=\"$ARBerkley\">Berk </font><font size=\"20\" face=\"$BitstreamVeraSans\">Vera</font>";

In my file, I have fonts named $ARBerkley and $BitstreamVeraSans, but you should replace those with the names of the fonts in your own file. Save your file and then test it with the Scaleform Launcher. You should see a button with two different fonts in it. You can click on that button and add event listeners, and do anything else that you would do with any other button. If your UI consists of lone buttons, then you’re practically done already. When you get your localized text from UDK, put it into a formatted html string like the one above, using the desired font, and set that as button.textField.htmlText.

But if your UI has button bars, you have a little more work to do. Next, you’ll need to make a new ActionScript file:

ButtonBarHTML .as

package  {
	
	import scaleform.clik.controls.Button;
	import scaleform.clik.controls.ButtonBar;
	
	public class ButtonBarHTML extends ButtonBar {

		public function ButtonBarHTML() {
			// constructor code
			super();
		}
		
		override protected function populateRendererData(renderer:Button, index:uint):void {
            renderer.textField.htmlText = itemToLabel( _dataProvider.requestItemAt(index) );
            renderer.data = _dataProvider.requestItemAt(index);
            renderer.selected = (index == selectedIndex);
        }

	}
	
}

[Edit: Since posting this, I’ve started using a custom button class instead of a custom button bar. I’ve learned that enabling/disabling buttons clears the htmlText. But with a custom button, in updateText you can set textField.htmlText = _label and leave everything else the same. Send it html the same way you would send plain text to any other button, and it’ll just work.]

Save that somewhere and then edit your fla’s source path at File > ActionScript Settings so that your fla can find it. Copy the button bar from CLIK_Components_AS3.fla into your fla’s library. Then change its name and class to ButtonBarHTML. Click on the check mark to validate class information just to make sure that Flash/Animate sees your custom ButtonBarHTML.as file.

Now, when you populate your button bar (via the button bar’s dataProvider), instead of sending just the text you want displayed, send it html, and you can set the font and the text depending on which language the game is running in.

Using the button’s htmlText property, you can also include images, change text color, and do other stuff with your buttons.

I don’t see it so clear, how do scaleform know what language to take ? Does it automatically detect from windows ?

I wrote this assuming that one would already know how to create localized strings and send them to the GFxMoviePlayer to label various elements.

What you would have to do is create various UnrealScript classes containing localized strings. Then when the GFxMoviePlayer needs to label a button or something, it should ask the game to send it a string using an ExternalInterface.call() or a delegate. The game will then return the localized string. So for example you might have this:

MyGFxMoviePlayer.uc

class MyGFxMoviePlayer extends GFxMoviePlayer;

var localized string ButtonName_Localized;

function string LabelButton()
{
	return ButtonName_Localized;
}

DefaultProperties
{
	MovieInfo=SwfMovie'MyGameMenu.MyGFxMoviePlayer'
}

MyGame.int

[MyGFxMoviePlayer]
ButtonName_Localized=My Custom Button In English

MyGame.jpn

[MyGFxMoviePlayer]
ButtonName_Localized=日本語のカスタムボタン

MyGFxMoviePlayer.as

package  {
	
	import flash.display.MovieClip;
	import scaleform.clik.controls.Button;
	import flash.external.ExternalInterface;
	
	public class MyGFxMoviePlayer extends MovieClip {

		public var button:Button;

		public function MyGFxMoviePlayer () {
		}

		public function labelButton():void {
			button.label = ExternalInterface.call("LabelButton");
		}

	}
	
}

Use that ActionScript file as the document class for a fla file. Publish the swf and import it into the editor in a package called MyGameMenu. Then when you open a MyGFxMoviePlayer in the game, and you call labelButton() somewhere, it will write some text on the button. If you run the game in English, the button will be labeled “My Custom Button In English,” and if you run the game in Japanese, the button will be labeled “日本語のカスタムボタン.”

Check it out. Buttons with images in them. And the image in the button at the bottom of the main menu is dynamic, changes according to localization settings. Font and text are dynamic too, based on localization. All without duplicating any menus.



The “Select Language” window gets populated from this section of a localization file:

ButtonBarLabels_Localized[0]="<img src=\"UnitedStates64\" width=\"32\" height=\"17\" /><font size=\"24\" face=\"$RegularRUS\"> English US</font>"
ButtonBarLabels_Localized[1]="<img src=\"Japan64\" width=\"32\" height=\"22\" /><font size=\"24\" face=\"$RegularJPN\"> 日本語</font>"
ButtonBarLabels_Localized[2]="<img src=\"China64\" width=\"32\" height=\"22\" /><font size=\"24\" face=\"$RegularCHN\"> 中文</font>"
ButtonBarLabels_Localized[3]="<img src=\"Spain64\" width=\"32\" height=\"22\" /><font size=\"24\" face=\"$RegularRUS\"> Español</font>"
ButtonBarLabels_Localized[4]="<img src=\"Brazil64\" width=\"32\" height=\"22\" /><font size=\"24\" face=\"$RegularRUS\"> Português</font>"

Pretty much every menu in the game that can be created with a label and a button bar uses the same MovieInfo. The only difference is the localization files that determine the text, and what the buttons do, determined by the UScript file.

1 Like

Thanks for the share. That will be useful!

1 Like

I don’t get it still this is a yes or no question, Does it automatically translate the language for you : P? No pressure though… : P
I Need it L :

No. You have to translate the text manually and put the text in the localization files. (In the example above, the localized text is placed in MyGame.int and MyGame.jpn.) Then the game will automatically choose the text based on which language the game is running in. (You can make the game run in English by running UDK.exe -language=INT and Japanese by running UDK.exe -language=JPN. Or you can change the language in engine.ini.) To change the language during gameplay (as I did in the screenshots above) you need access to the C++ source code.

1 Like

Good job on figuring that all out. I like what you have come up with, that is nice. Great job.

Thanks @Nathaniel3W, you have been one of the people who most helped me with unreal scripting. I will very soon add the translation option on my game, so this tutorial will be very useful.