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!
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.
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