How To Detect Object Moving In Blender Addon.

GOAL

Today’s goal is to develop addon to detect object’s property changes and call function. In my case, I created an addon to detect object moving and display the message “object <Name> moving” to the system console.

Environment

Blender 1.83(LTS)
Windows10

Method

Use handler

Use Application Handlers to call function by triggers. I used “bpy.app.handlers.depsgraph_update_post” for calling the function to check if the current object is moving in each time when the blender scene has changed.

Reference: Persistent Handler Example

import bpy
from bpy.app.handlers import persistent

@persistent
def obj_init(scene):
    # check if the bpy.context.object is moving or not

bpy.app.handlers.depsgraph_update_post.append(obj_init)

Add property to store location before move

I added property “before_loc” to compare current object location to the one before depsgraph updated. If the location changed, store new location to the property “before_loc”.

def register():
    bpy.types.Object.before_loc = bpy.props.FloatVectorProperty(name="before_loc", subtype="TRANSLATION")
def unregister():
    del bpy.types.Object.before_loc
@persistent
def obj_init(scene):
    if hasattr(bpy.context, "object"):
        if bpy.context.object.before_loc != bpy.context.object.location:
            print("object {} is moving".format(bpy.context.object.name))
            bpy.context.object.before_loc = bpy.context.object.location

bpy.app.handlers.depsgraph_update_post.append(obj_init)

The complete code

bl_info = {
        "name": "Detect Object Moving",
        "description": "Addon to detect object moving and print the name",
        "version": (1, 0),
        "blender": (2, 80, 0),
        "category": "3D View",
        }

import bpy
from bpy.app.handlers import persistent

@persistent
def obj_init(scene):
    if hasattr(bpy.context, "object"):
        if bpy.context.object.before_loc != bpy.context.object.location:
            print("object {} is moving".format(bpy.context.object.name))
            bpy.context.object.before_loc = bpy.context.object.location

bpy.app.handlers.depsgraph_update_post.append(obj_init)

def register():
    bpy.types.Object.before_loc = bpy.props.FloatVectorProperty(name="before_loc", subtype="TRANSLATION")
def unregister():
    del bpy.types.Object.before_loc

if __name__ == '__main__':
    register()