Get the camera position in each frame of the animation

Hello,

I am new in Blender and Python and I have the following problem:

I want to print the position of the camera in each frame of an animation. So I have tried the following code :


import bpy



def my_handler(scene):
    print("Frame Change", scene.frame_current)
    scene = bpy.data.scenes["Scene"]
    print(scene.camera.location)


bpy.app.handlers.frame_change_pre.append(my_handler)


I got the number of each frame but the camera’s position printed in the console is constant.

<Vector (-35.4940, -2.9554, 5.3437)>Frame 41
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 42
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 43
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 44
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 45
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 46
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 47
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 48
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 49
<Vector (-35.4940, -2.9554, 5.3437)>
Frame 50 <Vector (-35.4940, -2.9554, 5.3437)>`

I don’t know what is the problem!

Thank you

Try


import bpy



def my_handler(scene):
    print("Frame Change", scene.frame_current)
    #scene = bpy.data.scenes["Scene"]
    print(scene.camera.matrix_world.to_translation())


bpy.app.handlers.frame_change_pre.append(my_handler)

are you moving the cam with a constraint?

It works for me, I hit Alt-A to start the animation and then I move the camera with the G mouse.

Also as a side note if changes happen to the method “my_handler” and the script is run again, you will need to append the handler again. But you don’t want to append the same handler more than once. You see if you press the “Run Script” button 3 times and you go the console you will see this problem.

>>> bpy.app.handlers.frame_change_pre
[<function my_handler at 0x0000009A42290510>, <function my_handler at 0x0000009A42290598>, <function my_handler at 0x0000009A42290620>]

The most easy way is to clear all of the handlers in the beginning. Just to make sure you use only the fresh handler.


import bpy


def my_handler(scene):
    print("Frame Change", scene.frame_current)
    #scene = bpy.data.scenes["Scene"]
    print(scene.camera.matrix_world.to_translation())


handlers = bpy.app.handlers.frame_change_pre
handlers.clear()
handlers.append(my_handler)

P.S. There is another one more complex to check if the name of the function is in the handler list and remove that, but when you will need it you can ask.

Congrats.



    handler = bpy.app.handlers.frame_change_post 
 
    handlers = [f for f in handler if f.__name__ == "mat_driver_fix"] 
    for f in handlers: 
        handler.remove(f)


For testing purposes


handler.pop()

in the console.

Yes!! It works, thank you. No it was not a constraint! So what is the problem with the previous code?

If it was being moved by a constraint, like for instance copy location to another object, the constraint postitions the object without changing its location property, hence the need for matrix_world.to_translation. Without seeing your file I can only speculate…

If the previous code reports a location that is different from that in the properties box, then that is a problem.

Good one batFinger, I like that lambda expression.