0
$\begingroup$

Is there is a way to check when the Active camera has been changed? I'd like to change some Scene settings depending on the camera you look through, and I'm looking for a way to know when a new camera is set as the active camera.

I'd prefer to avoid having to create a custom function to replace the "Set Active Object as Camera".

Thanks!

$\endgroup$
2
$\begingroup$

Properties updates and handlers

enter image description here

  • Added a scene pointer property (x_camera for want of a better name) which points to a blender object type. The poll method lets it be narrowed down to those of type 'CAMERA'

  • Scene.x_camera has an update method for when this object is changed and changes scene camera to match.

  • Added the property to the UI in the scene panel. The benefit of this approach is the user can choose a camera, and run code based on this choice.

  • Next added a simple getter boolean property, cam_change that is false when our pointer property camera is not the scene camera

  • To handle other ways the active camera is set, eg keystrokes, or markers, a handler is used. The scene update pre handler ticks over a lot. Another boolean could be utilized to turn the handler on or off.

Test code below. Added a couple of convenience methods to uncomment and remove handlers and panel draw_methods.

import bpy
from bpy.props import PointerProperty, BoolProperty

def cam_changed(self):
    return self.x_camera is not self.camera

def cam_update(self, context):
    if self.cam_changed:
        self.camera = self.x_camera
        print("UI UPDATE")
    else:
        print("HANDER UPDATE")

def cam_update_handler(scene):
    if scene.cam_changed:
        scene.x_camera = scene.camera

def cam_poll(self, object):
    return object.type == 'CAMERA'

bpy.types.Scene.x_camera = PointerProperty(
        type=bpy.types.Object,
        update=cam_update,
        poll=cam_poll,
        )

bpy.types.Scene.cam_changed = BoolProperty(
        get=cam_changed
        )

def cam_draw(self, context):
    layout = self.layout
    scene = context.scene
    row = layout.row()
    row.alert = scene.cam_changed
    row.prop(scene, "x_camera")

bpy.types.SCENE_PT_scene.prepend(cam_draw)

# handler

bpy.app.handlers.scene_update_pre.append(cam_update_handler)


def remove_handlers(prefix, handler):
    handlers = getattr(bpy.app.handlers, handler, [])
    remove = (h for h in handers
            if h.__name__.startswith(prefix))
    for h in remove:
        handlers.remove(h)

#emove_handlers("cam_", "scene_update_pre")        

def remove_draw_funcs(prefix, panel):
    funcs = getattr(panel.draw, "_draw_funcs", [])
    remove = (f for f in funcs
            if f.__name__.startswith(prefix))
    for f in remove:
        panel.remove(f)

#remove_draw_funcs("cam_", bpy.types.SCENE_PT_scene)
$\endgroup$
0
$\begingroup$

I found a solution by using Animation Nodes add-on.

You just need to set different value of Pass Index (Object Tab) for every camera. And this node-tree will check camera's Pass Index and send its value to rotate Empty. Now you can extract rotation data from Empty and drive everything you need in the scene.

For example, Cube is rotating in accordance with active camera (all cameras are binded to timeline markers).

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.