It appears that this is not supported by blender. So here is my workaround.
I made a little script that will allow you to execute a function when the property of an object changes. I'm not used to blender modules so I didn't made a downloadable module out of it. But it's still pretty easy to set up.
Create the observer module
first, we need to execute a function every frame, this function will check if any property has changed and call the corresponding observer function.
- Add an empty to the scene.
- Add a pydriver to the empty (open the property panel (n) and then right clic on the location and select "Add Single Driver")
- Go in the graph window and open the "Drivers" display (clic on f-curve editor button in the bottom).
- Open the properties (n)
- Select the added driver in the list on the left.
- Remove any variable and modifier in the properties panel.
Just below the "Scripted Expression" button there is the "Expr" field enter in it the following :
This will call our frameUpdate function at every frame change.
Now that we are setup
create a new file in the text editor named
check the "register" option (this will create a new module loaded automatically with .blend) and add the following to the file:
#author : Vincent Picard
#list of all the observers.
observers = 
#This is to function to call in your scripts. use it to have your function called everytime an object property changes.
#object : Object to watch,
#property : property to be wathed.
#function to execute every time the property of the given object changes.
#function will be given this parameters :
# object : the object.
# value : new value of the property
# old : old value of the property.
# frame : current frame.
def observe(object, property, function):
#Called at every frame. This will call the function that are listening.
for observer in observers:
#make the function visible to scripted driver.
bpy.app.driver_namespace['update'] = frameUpdate
#Each time we call observe we create an observer object.
def __init__(self, object, property, function):
#if the property object needs deep copy
self.oldValue = getattr(object, property).copy()
self.newValue = getattr(object, property).copy()
#if the property object doesn't need it (and don't have a copy method).
self.oldValue = getattr(object, property)
self.newValue = getattr(object, property)
self.object = object
self.property = property
self.function = function
#Call the function if the object property changed.
def update(self, frame):
#if the object needs deep copy
self.oldValue = self.newValue.copy()
self.newValue = getattr(self.object, self.property).copy()
#if the object doesn't need it (and don't have a copy method).
self.oldValue = self.newValue
self.newValue = getattr(self.object, self.property)
if self.oldValue != self.newValue:
self.function(object = self.object, value = self.newValue, old = self.oldValue, frame = frame)
How to create an observer and use it.
- You now need to reopen you .blend, that way the "observer" module will be available.
You can now observe object properties and make a function to be call when it changes.
Create your script file (example) :
#define the function you want to be executed. this one as an example simply print old and new value when they are changed.
def updateAnimation(object, value, old, frame):
#register your observer.
observer.observe(bpy.data.objects["Cube.031"], "location", updateAnimation)
Run it, it will register your observer.
do not run the observer.py file, if you do then it will stop working and you will need to reopen the