Using After Effects for iPhone Game Animation Paths

My first post here and the title is really long.  Whatever!

I needed to create some smooth mostly preset animation paths for an iPhone game.  I didn’t want them to be completely random, I wanted to control the general feel of the motion.  But I also wanted it to have a random feel and not be exactly the same each time you see it.  So here’s how I did it, using After Effects and Microsoft Excel.

Recently I’ve been using Excel to organize and convert opengl vertex data.  This gave me the idea to pull path data out of After Effects, bring it into Excel to scale it, convert it a bit and format it into an Objective-C header file.  Sure maybe I could write an app for that, but it’s too specific and I’ve found that Excel allows really quick manipulation of data and if I need to customize one or two values that don’t follow the normal computation I can just type those in manually.

My idea was to create a table or array that would be a loop-able path.  Instead of storing the exact screen values for each ‘frame’ of the animation, I wanted to store the delta or change in position from each previous position.  As a simplified example, let’s say the object’s x value over 5 frames was to be at {10,15,17,23,25}.  Instead of storing those exact values I would store 15-10 or 5, 17-15 or 2.. and so on.  My table would be {5,2,6,2}.  If I start off the object at 10 and add the delta each cycle I get the same results.  Of course I’ll be doing this for both the x and y axis.

There are 4 advantages to doing it this way.  First is that you can choose to start the object off somewhere different and get the same animation motion with another starting location.  Second is if you loop through the array and keep adding delta values to your object’s x,y you get a repeating kind of motion.  Third is that you can shift the phase of the motion by starting the array index somewhere in the middle and get a different part of the swoop each time.  And finally, you can store off several versions of the move in the same array and either directly access or cycle through the different moves.  I suspect it’s a very common practice in game design.

In my application I needed a ‘swooping’ path that would repeat.  Think of leaves floating across the screen.  By creating a long swooping path that has seam-able ends, I can loop through the array over and over and get the same general feel to the ‘snoopiness’ every time.  But by randomizing or varying the starting index on the array the phase of the swoop can be different each time.  And in my case I’ve also placed several versions of the move so that it really has a unique feel each time it’s used.

Creating the move in AE

The first step was to create a move in After Effects.  For this I created a new solid that was 5×5 pixels.  Then keyframed it around to get my motion the way I wanted it.  Notice that here I have 5 keyframes.  I set my composition to 60fps, which is my target fps for my game.  This entire process was repeated for several different moves and to experiment until I got the motion I was looking for.

Next I had to convert the 5 keyframes into ‘baked’ keyframes for each of the 60 frames per second.  An important step is to duplicate the solid so that you still have the original one to go back to.  Soloing the copy of the solid with the move on it, I selected Transform Position in the timeline, and then Animation -> Add Expression from the menu bar.  I used the expression “transform.position=value” but just “value” might also work.

For each frame this feeds the value that’s calculated from the spline back to the position as a precise number.  Next was to use Keyframe Assistant -> Convert Expression to Keyframes, which took each of the x,y values along the path for each of the 60 frames per second and created new keyframes for them.

If you don’t bake the keyframes the only thing you can export are the 5 b-spline points, which isn’t very useful.  This way we can selectively export individual coordinates.

Converting, Scaling, Formatting in Excel

Selecting only the important transform.position keyframes in the after effects timeline, I copy and pasted them to a TextEdit document.  If you try it and you’ll see that there’s a bunch of info in there that you don’t need.  But a few lines down is “Transform Position” followed by a table of “Frame, X pixels, Y pixles, and Z Pixles”.  Reselecting just the numbers I copied again and pasted to an excel spreadsheet a few lines down.

I allowed Excel to do all the math and formatting for me.  First I have a line number that I created just to have an easy count of the data.  Next is the original values from AE.  That second column (B) is the frame number from AE and was ignored.  Column E was the Z axis and was all zero’s, so it was deleted. C and D is the source x,y.

My horizontal scale in After Effects was 720 wide and for the iPad I needed a width of 1024.  J2 is 1024/720 or 1.422.  Column F and G are scaled values to turn the 720 width into a 1024 width.  So the formula in F5 is


The $ signs absolute the scale cell of J2 so that when you copy that formula to the rest of column F & G it always references the same scale factor.

Next was to convert the exact numbers to offsets from the previous number.  The first thing to look at is the coordinate system of the device we’re going to.  The iPad / iPhone under opengl has an inverted Y axis.  (The image below is the coordinates I use for the iPhone.)

So the formulas for columns L and M take each value and subtract the previous value to get the change.  (Ignore the columns I and J because I didn’t use them.)


In the Y axis I reverse this so as to swap the polarity of the delta:


Side note: Of course you could also swap that in code by subtracting values each cycle instead of adding them.  Or reverse the left-right direction of the movement by doing the same thing.  Or even rotate the motion 90 or 270 degrees by using the x values on the y and visa-versa.  You could also scale the data in code as well, for example to rescale it from the iPad to the iPhone.  Experimentation!

Finally the formatting.  To make a cleanly formatted array in objective-c I want all my numbers to have the same number of digits, include commas and a tab between values.  Columns O and P have this formatting.  The formlula in O9 is:


It takes the value in L9, converts it to text with a formatting of 5 decimal digits, then concatenates a comma on the end.  This formula is copied to the entire column O and P.

Copying and pasting these two columns it will insert a tab between the two columns and the numbers will be formatted nicely in Xcode.  Then just add a }; to the following line to close up the array.

In my header I also add a constant definition for how many sets there are in the array.  A simple count or rows in Excel.

#define Leaf_Path_Array_Size 245

In Objective-C

That’s basically it.  The rest is just using those array values in the code to move the object a little bit each cycle.  I’m not going to post any entire code snippets today because the post is about the above process.   But I’ll briefly go over the theory behind it.

Now for a confession…  I still didn’t use these exact values in my project.  I tried that and while it does give you the exact path that you created in After Effects, it looked a little too stiff to me for the types of objects that I was animating.  I think for some types of elements in some games this would be the look I was after.  But for this I wanted something more fluid.  So I decided to buffer the values and use the path values as a trend, or influence, on the particles.  Particles?  Yes I used a simple particle method to manage the objects.

Another confession… In objective-c the proper way to do this would be to create a model and a model manager and use a leaf class to do all this.  I can’t be bothered with all that.  I just wrote 2 simple methods inside my main draw class and handled it with an array.  Very un-objective-c like, I know.. I don’t care.

So I had one method that manages the data, decides when to add new particles, moves them along, draws them, and then removes dead particles.  And a second method to actually do the work of adding a new particles.  I’m not going to go into all of that right now.  That’s for another post.  I’ll just give the code that I used to make this all work.

The “addNewParticle”-type method makes sure there is room for another particle in the array, picks a random starting point just passed the side of the screen, and sets up all the initial values for the individual leaf.

Then the “updateAndDrawParticle: delta”-type method applies the same movement to each particle in the array based on the time delta, which is the time in seconds since the last cycle.  The delta being passed it has a goal of 1/60th of a second, or .016667. Here is a simplified version (not the exact actual code) of the loop:

//add new particles
for (int i=0; i<particleCount; i++) {
  // rotate once per second
  particleRotation[i] += delta*120;
  // skip along in the path data by 2's
  // because evens are x and odds are y
  particleSpeedX[i] +=LeavesMotion_Path[pathAnimationIndex*2]*delta;
  particleSpeedY[i] +=LeavesMotion_Path[pathAnimationIndex*2+1]*delta;
  // draw that particle in here

if (pathAnimationIndex > Leaf_Path_Array_Size)

There you have it.  Some other time I’ll get into the particle system.  In this case I only have a few large particles, like 5 to 10, so I’m drawing each one individually.  If there were thousands of smaller ones I’d use another method to draw them all at once.

1 thought on “Using After Effects for iPhone Game Animation Paths

  1. Hey,

    Great article! I think this is exactly what I need. I am a little confused and I could use some help though.

    I am giving videos to my developers to show them how I want the animations within the app to move. However, when I get the app prototype back some of the animations are a little bit off.

    I want to be able to extract my Bezier curves from After Effects (Javascript) and give the developers the exact numbers to plug into their program (Codex/Objective+C).

    I didn’t understand everthing in the article, would you be able to clarify how to do this?


Comments are closed.