Loading a Unity SWF in Flex

With the release of Unity 3.5's Flash export option there are many new opportunities for Unity and Flash developers. Since my career has mainly involved working with both technologies, I wanted to try loading a Unity-exported SWF file into a Flex application to prove the possibility of a Flash game incorporating Unity content. It's straightforward to do, but the requirements aren't documented in one spot. This article should help solve that. It does not cover Flash-to-Unity communication, but it's the right place to start. Below is a short list of requirements that I'll be explaining:

  • Flex project must use at least Flex SDK 4.6
  • Flex project build should target Flash Player 11.1.0
  • Add the Additional Compiler Argument: -swf-version 13
  • The flash player embed needs to include the attribute wmode=direct
  • Your .mxml application tag might need to include backgroundAlpha="0"
  • Include the UnityShared.swc file in your project
  • Download the files provided by Unity in this forum post by Unity
  • Using Flex SDK 4.6 You must have at least Flex SDK version 4.6 to make sure your project has the neccessary Molehill and AIR APIs available. If you don't already have it, download it here and then set your Flex SDK version by going to: Project -> Properties -> Flex Compiler -> Configure Flex SDKs -> Add... Then select your downloaded 4.6 SDK folder. After selecting the folder, be sure to come back to select it from the list on the Configure Flex SDKs panel.

    Targetting Flash Player 11 Your project must build to Flash Player 11 because it's the first Flash Player to support molehill's 3D rendering. You won't be able to set Flex to use this version until you've set your project to use SDK 4.6. You can set your application to target Flash Player 11 by going to: Project -> Properties -> Flex Compiler Then check off Require Flash Player version and set it to 11.1.0. You will need Flash Player 11 installed on your computer to view the 3D content.

    Additional Compiler Argument Setting the swf-version to 13 allows the Unity SWF to utilize AIR 3 APIs that it requires. You won't be able to do this until you have your project set to Flex SDK 4.6, otherwise it will throw an error. To set the swf version go to: Project -> Properties -> Flex Compiler In the Additional compiler arguments text box be sure to include the argument -swf-version 13. You can read more about SWF versions from Adobe's blog.

    Using wmode="direct" In order for Stage 3D content to display, a Flash variable called wmode (window mode) needs to be set to equal direct. This requirement causes a Unity SWF to not open properly in a browser directly and you'll see some errors. The wmode attribute is set in the embed code running your Flash content. I set it in the following two places in my HTML and JavaScript:

    AC_FL_RunContent(
    		"wmode", "direct",
    		....
    
    if (hasRequestedVersion) {
    	// if we've detected an acceptable version
    	// embed the Flash Content SWF when all tests are passed
    	AC_FL_RunContent(
    			"wmode", "direct",
    	....

    And lastly make sure that the HTML embed tag has the attribute wmode="direct".

    Change the Stage Transparency I believe there are two stages when working with molehill. There is your normal stage layer that we've always known and loved. And then there is the Stage 3D layer. The Stage 3D layer is rendered behind the normal stage.

    If you load a Unity SWF into an empty stage you'll likely see a blank white screen. The trick is to turn the transparency of the normal stage to zero and it will reveal the Stage 3D content behind it. This can be done in your .mxml file by giving whatever application tag you use to have the attribute backgroundAlpha="0".

    The cool thing about the two stages is you could create UI elements in Flash that overlay your Unity content. The down side is I don't believe it is easily possible to show Unity content above Flash content. For instance your game probably couldn't have a pop-up window displaying Unity content unless you can easily detect and hide whatever Flash objects are overlapping it.

    Include the UnityShared SWC file To load and communicate with the Unity SWF you're going to need to include a SWC file called UnityShared.swc in your project. This file is created when you export a SWF from Unity. For convenience you can also download it from me. After moving the file into your project go to: Project -> Properties -> Flex Build Path Click Add SWC... and select UnityShared.swc. This SWC file contains a few classes made by Unity. The class we care about is UnityContentLoader.

    Loading Unity Content To load the Unity content you're going to need to look at this forum post provided by Unity and at least download the file entitled "AS3Communication_as3_src.zip". Add the two ActionScript files to your Flex project as well as the images. You will probably want to edit the file called SimplePreloader.as and change the line that says:

    unityContentLoader = new UnityContentLoader("unity-flash-small.swf", this, params, false);

    You want the string "unity-flash-small.swf" to be the name and path of the Unity SWF you want to load. You might even want to change this class to accept a string URL for the file you are loading to make it more reusable. This class can load in remote Unity SWFs from web servers, or it can load local files. Once you have this part set up the way you want, you can get things rocking and rolling with the following code wherever you want to load the Unity SWF in your project.

    import com.unity.UnityContentLoader;
    
    private var unityContentLoader:UnityContentLoader;
    
    private function startLoad() : void {
    	var loader:SimplePreloader = new SimplePreloader();
    	stage.addChild(loader);
    }

    This should be all you really need to get started with loading in Unity content to a Flash application. If you want to know about communicating with the loaded Unity content I recommend continuing to read this forum topic . To export a SWF file from Unity, read this page on their website.