Since using Unity, I’ve been trying to replicate a pipeline that’s similar to Flash. Being able to use Flash’s environment for hand-polished 2d animation just can’t be beat, unless you count custom developed tools. LWF from GREE shows promise in allowing you to bring your Flash animation into Unity, but there is some work involved in getting it to work!

donuts_lwfDemo made with LWF in Unity.

With the mobile version of DONUT GET!, I tried a homemade Sprite Animation approach. This worked reasonably for the requirements of the port but it was more trouble than anticipated given the size of the texture sheets needed for so many frames of animation. Sprite sheets ate up RAM like nobody’s business and easily crashed lower-end devices.

Late last year GREE announced a godsend, LWF. It’s an Open Source tool to export Flash animation from SWF’s into Unity or HTML5. This was around the time I released DONUT GET! on mobile (which was GREE integrated) and I was excited to try it out. Unfortunately, the first release required you to compile it yourself and the only info I could find was in Japanese. Later on I found out that GREE posted more information and a super helpful video walkthrough on the Unity forums.

FLA Setup

A few months ago I tried to make a demo bringing animation from DONUT GET! into Unity with LWF. I quickly found out that there are a whole bunch of gotchas.

  • Set FLA to Flash Player 7, ActionScript 1.0
  • Extremely limited ActionScript. I believe just gotoAndPlay/Stop level commands will work and FSCommands can be used to shoot events back to Unity. I haven’t tried this stuff!
  • No vector graphics. Vector graphics can be exported as images and re-imported as images.
  • MovieClips must only contain 1 image. Appears to fail with multiple images.
  • MovieClips can contain multiple nested MovieClips, just not in combinations with images it seems.
  • Alpha works properly.
  • All images must have Lossless (GIF/PNG) Compression. JPEG Compression will throw error.
  • For examples, (Limited) Demo FLA’s available at: https://github.com/gree/lwf-demo

Getting Started

GREE’s video gives a great rundown of how it works, check it here: http://www.youtube.com/watch?v=K7awPpMplIk

Download LWF here: http://gree.github.io/lwf/

You’ll find the unitypackage in the LWF zip file in the path “csharp/unity/dist/lwf.unitypackage”. Import this into your Unity project to access the LWF library.

LWFS, with an ‘S’, is a program that will run in the background on your computer and automatically converts SWF’s into LWF format. It creates a folder on your desktop called “LWFS_work” and “LWFS_work_output”. In the “LWFS_work_output/unity” folder, you’ll find a folder that was created with the same name of the SWFs you convert. You can download an executable of LWFs here:

Copy that folder into the “Assets/Resources” folder of your project. If you don’t have a “Resources” folder, create one.

 

How it Works

I’m not gonna act like I’ve sorted through and analyzed all the code to understand how it works. From what I understand though, it rips apart all of the MovieClips and grabs the images they contain. The .bytes file seems to carry all the information about the depth sorting, movement, timing, etc.

lwf_pieces
Here’s what LWFS spits out.

Documentation is a bit limited so I’ve been trying to figure it out as I go along with trial and error.

Some Sample Code

I made a little wrapper class to make it a bit easier to use. You can set the texturePrefix and lwfName strings in the editor. These are paths to the LWF files.

lwfName – This is the path in the “Resources” folder to the .bytes file. In my case it was “lwf/demo_sprite_walk.swf/demo_sprite_walk” because I have all of my animations in a “lwf” folder within “Resources.”

texturePrefix – This is a path to the folder containing the images. In my case, it was “lwf/demo_sprite_walk.swf/”. Just remove the “lwf/” if you’re not putting them in an “lwf” folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using UnityEngine;
using System.Collections;

public class SimpleLWFObject : LWFObject {
   
    public string texturePrefix;
   
    // Use this for initialization
    void Start () {
        Load(lwfName, texturePrefix);
    }
   
    public void PlayAnimation(string name) {
       
        Debug.Log("Play LWF Animation: " + name);
       
        switch(name) {
            case "walk_right":
                StopMovie("guy_left");
                PlayMovie("guy_right");
                SetAlphaMovie("guy_left",0);
                SetAlphaMovie("guy_right",1f);
                //SetVisibleMovie("guy_right", true);
                //SetVisibleMovie("guy_left", false);
            break;
           
            case "walk_left":
                StopMovie("guy_right");
                PlayMovie("guy_left");
                SetAlphaMovie("guy_left",1f);
                SetAlphaMovie("guy_right",0);
                //SetVisibleMovie("guy_left", true);
                //SetVisibleMovie("guy_right", false);
            break;
           
        }
       
    }
   
}

And from there, I can call the animation I want with something like “lwfObject.PlayAnimation(“walk_left”);”

In the FLA I setup, it contains two MovieClips with the instance names “guy_left” and “guy_right”. They’re both the same MovieClip, one’s just flipped horizontally to face left. This was a quick and dirty example to get an idea of how to go about bringing some lightweight interactive character animation into Unity.

Please note that I’m extending LWFObject for this class. I just couldn’t get LWFPlayer to work properly for me. For some reason when I tried it, it would just use one image for all of the different body parts.

The most major problem I found was with the depth sorting. When using a perspective camera, you’ll encounter Z-fighting depending on the viewing angle. This can be a problem with character animation when the arms are popping through the head or the legs are appearing behind the body. Also because of this sorting, I couldn’t just flip the walk animation around on the Y axis because the sort-order would be reversed. So to remedy it, I had a “guy_left” and “guy_right” MovieClip in the FLA. “guy_left” starts with an alpha of 0, which is why you don’t see it on start.

To remedy the sorting issue, I used an orthographic camera. It works, but things are no fun without perspective! :(

Also, I found a way to get around this sorting issue. You can change the camera’s sorting method like so:

1
gameObject.camera.transparencySortMode = TransparencySortMode.Orthographic;

This seems to resolve sorting issues with a perspective camera.

Animations using this technique use a fraction of memory as my Sprite Sheet method. I’m planning on using this technique for animated scenes in our next game The Crazy Program to see how they work out.

I have to thank GREE for their open source tools! LWF is great and I’m looking forward to checking out their Unity WebView as well.

More Resources

  • KyunTae Ethan Kim

    The post is really helpful to me. Thank you very much~!

  • http://www.Drawalot.com/ Shaun D. McMillan

    It’s a real shame that we can’t just keep using flash. I’d love for my students to begin making mobile games, but I don’t know if it’s better to have them learn Corona SDK, or to use Flash type pipelines, etc. First, I’m thinking to have them create some simple python games. What are all the other old flash game designers up to these days?

    • http://www.sokay.net Bryson Whiteman

      I’m glad you asked Shaun, there are lots of options for not having to use code or little code. Whenever something goes away, something better takes its place! Unless you want to get into the argument that vinyl is superior to digital.. haha!

      Here are tools, easy to use, and mostly with free options.

      > Game Maker – http://www.yoyogames.com/gamemaker/studio

      > Contstruct 2 – https://www.scirra.com/

      > Stencyl – http://www.stencyl.com/

      I think they all allow you to export to HTML. I think nothing beats Flash as far as animating along with coding, but these tools are very easy to get some logic and stuff moving around. I haven’t used any of them, but check out the tutorial videos on YouTube. Should be able to figure them out in a weekend.

      Because it can be hard to understand how game logic works, beyond understanding what the code syntax is. I think it might be easier to get started with something not so reliant on code to teach basic logic of how a game works. All these tools I believe allow you to actually go in and code stuff to customize things in more specific ways. I think the big prob getting started is being overwhelmed. So easier initial feedback comes, the better!

      • http://www.Drawalot.com/ Shaun D. McMillan

        Awesome, thanks Bryson! I actually look forward to the students trying some coding, but the last thing I want is them is getting overwhelmed. As long as there are enough tutorials to help them each step of the way I’m sure they’ll be fine.

  • Ivo Gregurec

    Hi! So far LWF has much better results then UniSWF except for placing animation on object (and not somewhere in the air). Have you figured out how to fix that in case we’ll use collisions or some other interaction? Thank you in advance!

    • http://www.sokay.net Bryson Whiteman

      As far as I know, the only way to pass data from the .swf to Unity is with “fscommand()” and that’s basically limited to events. Just thinking on the fly, if you really needed to do a hit detection, if you could get the X & Y value of nested MovieClips, I suppose you could use that to find the 4 corners by placing movieclips (topleft, topright, bottomleft, bottomright). I have NO IDEA if that’s possible but I think it’d be the only way to go around it with handling all the logic in Unity. Good luck, thanks for the comment!

      Also, here’s a guide:
      http://gree.github.io/lwf-demo/pdf/FLASHforLWFproductionguideline.pdf

      • Ivo Gregurec

        Thank you for the info but I still have few more questions:How does this hippy in your demo “know” where is the end of the screen? The simplest solution would be to lock his movement on Y and Z axis and put some “physical” boundaries… But where is the object that is running the script? On the same location where the animation appears or somewhere left, under and further? (Or somewhere else?)

        • http://www.sokay.net Bryson Whiteman

          LWF will take 0,0 from the .swf (top-left corner of the stage) and map that to the center of the Gameobject. In this example, I placed the hippie MovieClip at 0,0 on the Flash stage. The center of the MovieClip is between the feet of the hippie. To move it around is a simple script that would work on any Unity GameObject. Just limited movement on X between -200 and 200, for example.

          In the code in this example I focused on being able to stop any play separate animation from the swf, controlling them from Unity.

          • Ivo Gregurec

            Thank you once again! It would be amazingly releasing if I could figure out how to remove that offset…

  • Ivo Gregurec

    Hey! I’ve tried once again and now it’s even crappier :(

    Do you have any idea?

    • http://www.sokay.net Bryson Whiteman

      It’s hard to tell what’s going on in the video. I’m not sure where the center is actually supposed to be. But it looks like youre just placing the characters in the center of the swf. The feet of the characters would be the top-left corner of the stage in Flash. So when you’d export the swf, they’d actually appear off screen.

      I think in the vid you were also showing that the characters weren’t moving with the GameObject? I couldn’t tell. But make sure you try extending LWFObject as I couldn’t get things to work correctly with LWFPlayer. And if LWFObject isn’t working for you, try LWFPlayer! ;)

      • Ivo Gregurec

        You were right! The center of coordinate system in Flash is the pivot point in Unity. But it took me some time to percept it that way in 3D… Now I’m trying to navigate the .swf timeline from Unity. There’s an example for javaScript in HTML but I can’t figure out how to use it in Unity :/
        I was thinking about something like:
        onEvent(foo){
        gotoAndPlay(“bar”);
        }
        Thank you once again!