# How can I get the location of an object at each keyframe?

I'm trying to track the (x,y,z) location of an animated object. For a small test, I translated the default cube ('Cube') along the x axis and baked keyframes. The animation plays fine.

I adapted the suggestion for this question to try and print the location at each keyframe.

import bpy
cube=bpy.data.objects['Cube']
for f in cube.animation_data.action.fcurves:
for k in f.keyframe_points:
pos=cube.location
print(pos)


Run from the shell, the output is

<Vector (0.0000, 0.0000, 0.0000)>
<Vector (0.0000, 0.0000, 0.0000)>
<Vector (0.0000, 0.0000, 0.0000)>
...
<Vector (0.0000, 0.0000, 0.0000)>


If I go to the last keyframe and execute cube.location, it correctly returns

Vector((6.924227714538574, 0.0, 0.0))


How can I get the location at each keyframe?

• Would using bpy.context.scene.frame_set(frame) and reading cube.location be a bad idea? – kilbee Dec 17 '13 at 23:18
• And then iterating through the frames? It doesn't seem like a bad idea. My sum total Blender experience is currently measured in hours, so anything that seems like it might work sounds good to me. – kmm Dec 17 '13 at 23:31
• Yes, exactly. cube.location reads the location from current context frame, thats why you are getting the results from the frame you run the script from. So to get the right results with cube.location you need to change the context with the bpy.context.scene.frame_set(frame). – kilbee Dec 17 '13 at 23:45

The reason your script was returning 0, 0, 0 is because you were printing the location of the object on the current frame.

Print the location of the cube object the same number of times as there are number of keyframes.

So as mentioned by kilbee you need to set the scene frame to the frame that the keyframe is on in order to read the location of the object on that frame.

By combining your code with kilbee's:

import bpy

ob = bpy.context.object

for f in ob.animation_data.action.fcurves:
for k in f.keyframe_points:
fr = k.co[0]
bpy.context.scene.frame_set(fr)
pos=ob.location
print(pos)


This way you only check frames with keyframes, as opposed to checking every frame.

Anyway to get the data you want (for frames for example 1-40):

for frame in range(1,40):
bpy.context.scene.frame_set(frame)
print(cube.location)


Upside is you dont have to bake the animation to get the data for each frame, downside is that with complex scenes it might be very time consuming to execute the script.