# Location of an object at a specific frame

I have a animation where one object moves through the 3D space. How can I get the location of this object which it has at a specific frame?

I tried something like this:

obj = bpy.context.active_object
ol = obj.location

# set current frame to 1
bpy.context.scene.frame_current = 1

pos_1 = (ol.x, ol.y, ol.z)

# set current frame to 5
bpy.context.scene.frame_current = 5
pos_5 = (ol.x, ol.y, ol.z)

# set current frame to 10
bpy.context.scene.frame_current = 10
pos_10 = (ol.x, ol.y, ol.z)

# set current frame back to 1
bpy.context.scene.frame_current = 1

print('Frame 1 {0}, id: {1}'.format(pos_1, id(pos_1)))
print('Frame 5 {0}, id: {1}'.format(pos_5, id(pos_5)))
print('Frame 10 {0}, id: {1}'.format(pos_10, id(pos_10)))


But the output for all Frames is the same except for the id's. So, how can I get the position of an object at a specific frame?

The "cleanest" answer is to look into the obj.animation_data.action.fcurves list to find the ones with data_path=="location" and use

loc[fc.array_index] = fc.evaluate(frame)


to evaluate them. Things get tricker if you have NLAs or drivers. It makes me wish the animation_data property had an evaluate(data_path, frame) method.

Then again, you might be able to just bpy.context.scene.update() after each frame_current= in your original version.

• When I look into obj.animation_data.action.fcurves list I find multiple items with data_path == 'location'. It seems that for each channel (x, y, z) there is one item in the list. Is there a way to distinguish which channel corresponds to which axes? – Miguellissimo Aug 7 '14 at 21:43
• Yes, you distinguish them using fc.array_index. I guess I didn't explain why I did that in my code example. – Mutant Bob Aug 8 '14 at 14:45
• Cleanest depends on your purpose, While fast and useful in some cases - this wont take a lot of things into account, Parenting, constraints, drivers, physics sim. – ideasman42 Aug 8 '14 at 16:44

Try using frame_set() instead of directly setting the current frame:

import bpy

obj = bpy.context.active_object
ol = obj.location

# set current frame to 1
bpy.context.scene.frame_set(1)

pos_1 = (ol.x, ol.y, ol.z)

# set current frame to 5
bpy.context.scene.frame_set(5)
pos_5 = (ol.x, ol.y, ol.z)

# set current frame to 10
bpy.context.scene.frame_set(10)
pos_10 = (ol.x, ol.y, ol.z)

# set current frame back to 1
bpy.context.scene.frame_set(1)

print('Frame 1 {0}, id: {1}'.format(pos_1, id(pos_1)))
print('Frame 5 {0}, id: {1}'.format(pos_5, id(pos_5)))
print('Frame 10 {0}, id: {1}'.format(pos_10, id(pos_10)))


Directly setting the current frame does not update all the animated values and re-evaluate drivers, etc. so the object position is not updated.
Using frame_set() will update everything, so the location is printed as expected.

• frame_set() still doesn't update location for me. – rfabbri Sep 8 '15 at 5:17
• huh, frame_set() worked for me, while scene.update() did not. Strange... – JonathanK Jul 14 '17 at 12:52
• using bpy.ops.rigidbody.bake_to_keyframes() at the beginning before frame_set() solved the problem for me – dome May 9 '20 at 14:44