3
$\begingroup$

so I'm having trouble with this script:

import bpy
import mathutils

cam = bpy.context.scene.objects['Camera']
obj = bpy.context.scene.objects['Cube']

def drive_shapekey(scene):
    obj_mat = cam.matrix_world.inverted() * obj.matrix_world

    obj_eul = obj_mat.to_euler('XYZ')
    cam_vec = obj_mat.to_translation().normalized()
    obj_vec = mathutils.Vector((0.0, 1.0, 0.0))
    obj_vec.rotate(obj_eul)
    difference = cam_vec.dot(obj_vec)

    key1 = obj.data.shape_keys.key_blocks["Key 1"]
    key1.value = difference


pre_handlers = bpy.app.handlers.scene_update_pre
[pre_handlers.remove(h) for h in pre_handlers if h.__name__ == "drive_shapekey"]
pre_handlers.append(drive_shapekey)

It's supposed to change a shapekey ("Key 1") value, based on the angle and position of a Camera relative to the position and angle of the Object possessing this shapekey.

Of course I have named all objects and shapekeys accordingly (at least I'm pretty darn sure). It does not run in 2.8 Eevee (didn't test cycles). The error I get is:

'bpy.app.handlers' object has no attribute 'scene_update_pre'

Which I looked up on google ofc, and apparently a number of commands from 2.79 don't work in 2.8 anymore, including some in this script.

So this thread talks about using the new commands instead. Apparently I am supposed to use the dependency graph instead of this bpy...sceneupdate-thingy.

I've never written anything in Python before and I have no clue about most of the code (apart from obvious stuff like the matrices and that def probably stands for definition or define.).

If someone could fix this script for me, I would be very happy. An explanation would be great, too, but don't waste your breath if you have better things to do. I just need it to work. Thanks in advance. :)

$\endgroup$

1 Answer 1

5
$\begingroup$

There are two thing that need to be updated:

  1. Matrix multiplication is now written using @
  2. bpy.app.handlers.depsgraph_update_pre should be used as handler

Unless I've missed something, this should be all the changes that are necessary.


import bpy
import mathutils

cam = bpy.context.scene.objects['Camera']
obj = bpy.context.scene.objects['Cube']

def drive_shapekey(scene):
    obj_mat = cam.matrix_world.inverted() @ obj.matrix_world

    obj_eul = obj_mat.to_euler('XYZ')
    cam_vec = obj_mat.to_translation().normalized()
    obj_vec = mathutils.Vector((0.0, 1.0, 0.0))
    obj_vec.rotate(obj_eul)
    difference = cam_vec.dot(obj_vec)

    key1 = obj.data.shape_keys.key_blocks["Key 1"]
    key1.value = difference


pre_handlers = bpy.app.handlers.depsgraph_update_pre
[pre_handlers.remove(h) for h in pre_handlers if h.__name__ == "drive_shapekey"]
pre_handlers.append(drive_shapekey)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .