We recently released Donut Get! on iPhone and Android. It was originally developed in Flash and we made the mobile ports in Unity. One of the challenges of porting was figuring out how to bring the game’s Flash animation into Unity. Here’s the “quick ‘n dirty” solution I came up with.

Exporting Animation Spritesheet from Flash

The first step was figuring out a good way to export the character animation from Flash. I needed a program that could export a sheet at a uniform size that would be in power of 2’s so it’ll work as a texture (256×256, 512×512, 1024×1024, etc).

I ended up using Keith Peters’ SWFSheet, it loads a swf and allows you to an export a spritesheet from it. I created an FLA for each animation with the dimensions of 256×256. I placed the cop Movieclip in the center, extended the timeline to the appropriate amount of frame and let ‘er rip!

The result is a sprite sheet image that looks like this. I exported it at 2048×2048 but dropped it down to 1024×1024 within Unity for its release.

The Fuzzy Textures Edges Removal

You want to import your textures into Unity as PSDs, especially if there are alpha channels. Once imported, Unity can convert it to whatever type of texture you need with the texture properties panel. One problem I encountered early one was fuzzy white edges around the black outlines of the characters and backgrounds. I found a good trick to get around the problem on Unity Answers.

Download and install the Flaming Pear “Free Plugins” pack (near the bottom of that list)

Open your PNG in photoshop.

Go to Select -> Load Selection and click OK.

Go to Select -> Save Selection and click OK. This will create a new alpha channel.

Now Deselect all (Ctrl-D or Cmd-D)

Select Filter -> Flaming Pear -> Solidify B

I jacked this directly from the thread here. Also in my PSD I made a copy of the original, hid it, and applied the filter to the copy just in case I needed to revert back to the original. I did encounter issues with the alpha channel not working correctly sometimes, you may also have to delete the “Alpha” channel in the Photoshop Channels window to try again.

The Plane

Unity is a 3d game engine. As such, I needed to create a 3d world for my 2d artwork. I used the textures on planes, like billboards. The problem with Unity’s built in plane is that it has too many subdivisions so it uses a lot of unnecessary polys. Fortunately on the Unity forums, I found a CreatePlane.cs script that created a plane models for me. I tried to match up the proportions (width vs height) to a similar ratio as the images, so I didn’t have to scale the models for them to look correct in game. The result was something like this:

Yeah, it looks 2D but it’s all 3D mang!

The 2D Shader

For DONUT GET! I needed a simple shader that didn’t have any lighting and also had transparency. I found some Unlit/Transparent shaders that worked well but I needed something that allowed double-sided polygons. I also needed a Color channel to use to apply tints and alpha fades. Here’ what I came up with:

The basic ideas I used to write this, I learned from this tutorial. I had used that idea of scaling the texture size to work out a system for creating tile-based stages with spritesheets. I adapted that class to make an animation class, and learn a bit about coroutines in Unity.

The Warnings

This may not be the perfect solution but its a start. This was all I needed for Donut Get! but there were some issues by using this exact same code.

This totally wastes texture space. Many animations in the game were only using 50-70% of the texture sheet size. These texture sheets can eat up a lot of mobile memory quickly, and that’ll crash older phones and tablets easily, so you only want to use as much as you need. Ideally, this code would allow multiple animations per sheet, allowing you to select which tile will be the start of the animation.

There may be other bugs or errors I didn’t encounter for this game, if you’ve got suggestions I’m down to listen! 😉

Related

Bryson is the guy behind all of the Sokay creations. Heading artwork and development, he's determined to make sure each game has a "distinctively Sokay" quality to them. He's always looking forward for a chance to experiment with new technologies to explore exciting ways to achieve fun.

Let me ask, how did you handle animation on character movement? I’ve been able to implement general animation but having animation for character movement “right”, “left”, and so forth is presenting its challenges. Can you shed any light on this for me?

Sorry, I forgot to put in more details about how to actually implement this. Let me recall how it works…

In the case of separate animations, let’s say you have a “stand” and “walk” animation. You will drop 2 SpriteAnimation classes onto your GameObject.

To setup each SpriteAnimation you have to give it a name, using the public “name” variable in the editor. That’s the name that’s used with the PlayAnimation() method ( i.e. PlayAnimation(“walk”);)

Next, you need to know which spritesheet to use for that animation. Keep in mind that this is a ghetto way of doing it, only 1 animation per sheet. So for the SpriteAnimation to know which sprite image it’s using, drop the corresponding image onto the public “sheetTexture” variable in the editor.

Then setup the number of frames, how many rows and columns of frames their are in the image, in my case I used 8×8 images. The size of each individual frame (256×256 in my case).

Update rate is how many milliseconds it updates a frame. I used something like 0.01, which is about 60fps. This is ghetto, you can rewrite it to take in a number which represents the framerate instead.

Also, for the left/right animations. I did all animations facing right, and I just flipped the rotation on the Y axis to 180 when I wanted it to face left. This way you only need half the animation. For this reason I needed to make a special shader that was double-sided. Because default shaders will only display the normal side.

Honestly, this script was a good learning experience. But looking into tools like ex2D ( http://www.ex-dev.com/ex2d/ ) it might be more worth it to just buy a tool that does everything you might to need. I haven’t used it yet, but I’m going to try it out since it does everything this script does and a lot more.

beez

Hi! Can you explain the last function? And wich is the type identifier for this words (currentAnimationName, currentAnimation). And in GetComponets(); what is the component? I try the script component but im not sure. Thanks!

public SpriteAnimation aniStand;
public SpriteAnimation aniWalk;
public SpriteAnimation aniJumpUp;
public SpriteAnimation aniJumpDown;

————–

So on the PlayerClass.cs GameObject, I dragged a SpriteAnimation.cs component onto the game object for each animation. One for “stand”, “walk”, “jumpUp”, “jumpDown”, etc. With the SpriteAnimation component on the GameObject, you drag the spritesheet into the public sheetTexture variable in the editor. Then give it the name (like “stand”), then set up the sheetWidth/sheetHeight variables, framerate, etc.

In PlayAnimation(), it searches for all SpriteAnimation components and stores them in an array. Then it loops through the array to find the ‘name’ that matches the _name parameter passed into PlayAnimation(). I keep track of the currentAnimationName so that it doesn’t play an animation that’s already playing.

I hope that helps!

beez

Yes! I do exactly this but i dont understand why nothing is happen. My player class:

Hey beez, thanks for posting the image. That helps a lot. It seems like you have things mostly setup correctly here here’s what you need to change.

– Sheet Width = 4, there are 4 columns of frames going from left to right.

– Sheet Height = 2, there are 2 rows of frames going from top to bottom.

– Tile Width & Tile Height = the size of an individual frame. It looks like your character is taller that it is wider, so I think it would be something like 128×256 for example.

– Update Rate, this should actually be something like 0.03. This is not a framerate but how fast it should be updating. So if you want 30fps, it should equal 1/30. Sorry, this is unintuitive. Since you’ve set it to 10, it’ll only change frames every 10 seconds.

In your Start() function just use PlayAnimation(“idle”) and it SHOULD work. I hope it works! haha

beez

I setup the values like you said now and when i click in play button unity crash. I understood something better now, but it doesn’t work. Sorry for all this situation and thanks for the support.

I’m sorry it’s crashing now. I can’t really say what the problem is without seeing how the project is setup. If you’re still having problems I’d suggest reading through this tutorial that gives a better explanation for how the sprite animation is handled, http://www.rebelplanetcreations.com/downloads/Other/Tutorials/HowToMakeAGameInUnity3D.pdf

Ewaughok

Since you developed the game in Flash, why not use adobe AIR and publish it to both iOS and Android from Flash? It’s the obvious method. To duplicate your game programming (and more) in Unity seems like a waste of man-hours to me. If you had developed this game in Unity first, then your effort makes sense …

I don’t know if you have experience with the AIR Exporter, but it’s pretty garbage. It’s improved a ton in all these years, but it’s still just barely usable.

Donut Get! wasn’t the most efficiently coded game as I spent a great deal of focus on the visuals. I used a lot of “quick & dirty” Flash techniques to get it to look the way it does. For mobile w/Flash, I’d probly have to blit the screen as bitmaps and it’d just crash the device due to the sheer amount of unique animation and art in any of its 3-mini games. It didn’t look too promising given that it was already bringing desktop machines to its knees. 😉

It’s also kind of a mess because it’s essentially 4 or 5 different swfs merged together, which the AIR exporter didn’t seem to like.

AIR works well if you’re making simple games with AIR export in mind as you develop it. For the kinds of games I make — usually action driven with lots of character animation — it doesn’t work too well. I wish this wasn’t the case, but I’ve gave up on Adobe a long time ago.

Porting to Unity was actually very useful to me. Since I didn’t have to worry about creating the assets, I could focus on figuring out how to bring my Flash animation and artwork into Unity, something I’ve been intending to do for years. It’s easier than starting on a new platform from scratch.

Thanks for the comment, yo!

Ewaughok

Okay, that makes sense. I’ve worked with AIR for about 4 years now and have had good results, but given the facts about your development approach, I can understand your shift to Unity.

My own experience with Unity on mobile is that it is molasses. Glad you like it.

From my perspective, any improvements to Flash have been like putting a band-aid on a gunshot wound. Yeah, it’s a little better but it’s not really good enough. The biggest problem with Flash for me has been speed, and I loved Unity from the get go because of the hardware acceleration across the board.

Adobe’s added hardware acceleration to Flash but making it require Stage3D sort of defeats the purpose to me, you don’t really get any of the great animation timeline tools of Flash or the awesome 3D tools of Unity. If I have to jump through hoops, I’d rather jump through Unity hoops, as evidenced by this blog post! 🙂

I’d really love for AIR to work for me but I’ve been focused on moving past Flash, although I’m still trying to keep it as part of my pipeline. It’s still an outstanding UI and animation tool. I would have liked to use AIR to port my older games, but it doesn’t even support AS1/2. Typical Adobe disappointment.

I’m glad you’ve been successful with AIR, that’s really dope. I’ve partly just been anxious to move onto something different because I’ve been so deep in Flash for such a long time.

Peace!

pradeepk

How are u maintaining resolution for all android devices?
Are u changing Camera view port or Scaling model.?
Do u have any Camera Adjuster class?

A little Pluto inhabitant crashed in Earth. Now it’s his epic journey to
climb to Pluto again. On his way to Pluto he has to face different
adventure like jumping, climbing, flying spaceship, and fighting with
snake, leopard, mountain goat and aliens. This free version contains
first jungle level.