# Handler frame_change_pre doesn't work in render

this works in viewport but not in render.

import bpy
from math import *

def frame_handler(scene):
z = scene.objects['Lift'].location[2]
scene.objects['Text'].data.body = str(floor(z / 4.0) - 2)

bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(frame_handler)


How to get it working in render? I've read this answer and changed from "bpy.data.objects" to "scene.objects" as already seen in the script. What am I missing? Blender v. 2.81.16

Edit. Tried that depsgraph thing mentioned in comments and changed to frame_change_post:

import bpy
from bpy.app.handlers import persistent
from math import *

@persistent  # maybe not relevant but doesn't harm anything?
def frame_handler(scene, depsgraph):
z = scene.objects['Lift'].evaluated_get(depsgraph).location[2]
scene.objects['Text'].data.body = str(floor(z / 4.0) - 2)

bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_post.clear()
bpy.app.handlers.frame_change_post.append(frame_handler)


Now the Text doesn't show up at all in rendered (but works in viewport).

• Does this answer your question? Sun object not moving when Rendering Animation Feb 26 '20 at 17:47
• @lemon Unfortunately I don't get a solution there. Feb 26 '20 at 17:55
• Should use frame_change_post instead (if possible) and with the depsgraph indicated above. Feb 26 '20 at 18:07
• Possibly related: blender.stackexchange.com/questions/161758/… , haven't tried with evaluated object as suggested by @lemon Feb 26 '20 at 18:10
• Point of link being: If you render the animation as single image and change frame in script, it renders the changed body of font object. Feb 26 '20 at 18:24

## 2 Answers

The answer is similar to this question. Though all this is new from 2.81.

So here are some little more information (as far as I understand all this, which seems to be new thing along the current versions).

To make your script work, you can change it to:

import bpy

def frame_handler(scene, depsgraph):
#print(depsgraph)
obj = scene.objects['Cube']
obj = obj.evaluated_get(depsgraph)
scene.objects['Text'].data.body = '{0:.2f}'.format(obj.location.z)

bpy.app.handlers.frame_change_post.clear()
bpy.app.handlers.frame_change_post.append(frame_handler)


Here frame_change_post is used. But following this documentation:

This can be used, for example, to alter scene prior it gets rendered.

So the result will be what you want to do.

In the script above I've changed the rounding for Z. That allows to confirm that 'post' is before rendering. If object Z position is 10 at frame 10, the text object will display 10 at the same frame.

Additionally, depsgraph is for dependencies graph. That means a data provided in the API to take into account the fact that during animation (or others) the object state varies due to what it depends on.

frame_change_pre has no depsgraph parameter in 2.82.

• Now it works but behaves strangely! The Text object drifts vertically as the lift moves, or that's what appears in the render result. Maybe the situation is too complex. Both the camera and the Text are parented to the Lift object. Feb 26 '20 at 20:47
• Well for this other aspect you should share more details and maybe a part of your blend file to reproduce the situation. I suggest you ask another question about that. Feb 27 '20 at 7:08

In sequence-view:

• click View menu item
• click Sequence Render animation

This will correctly export an animation with frame_handler