# adding a delay for a driver

I have a driver on a keyshape which is controlled by an object moving in the scene. I would like to add a 5 frame delay so the keyshape changes are delayed by X frames.

I am using scripted expression currently it has (var+2.73)*.1

so if its possible to add what ever is required to make a delay.

cheers Shaun

Similar to this answer, we can use a driver function to capture the relevant details - but instead of using the values to calculate the velocity and/or acceleration, we can simply store the previous data value into a queue and retrieve the value after the specified number of frames.

Here's the code you'll need - paste it into a Text Editor window named something like 'delay.py'. Tick the 'Register' checkbox to ensure it's run automatically whenever the .blend is loaded - or just run it manually using the 'Run Script' button.

import bpy

attributes = {}

def drv_delay(frame, attr, delay, value):
# Used to delay the value by a specified number of frames.

# Determine whether we already have a value for this attribute
if attr in attributes:
attribute = attributes[attr]
else:
# Not found - create a new record for it and store it
attribute = {'frame':frame, 'dataqueue': []}
attributes[attr] = attribute

if frame <= 1:
del(attribute['dataqueue'][:])

# Only store the value on change of frame (to guard against being called multiple times per frame)
if frame != attribute['frame']:

# Store this value in the queue
attribute['dataqueue'].append(value)

# Discard any elements that are more than the delay period
while len(attribute['dataqueue']) > (delay+1):
del(attribute['dataqueue'][0])  #remove one from head of the list

# Store frame
attributes[attr]['frame'] = frame

#return the value at the head of the list
if len(attribute['dataqueue']) == 0:
return value
else:
return attribute['dataqueue'][0]

if 'drv_delay' in bpy.app.driver_namespace:
del bpy.app.driver_namespace['drv_delay']
bpy.app.driver_namespace['drv_delay'] = drv_delay


The script defines a driver function and registers it in the driver namespace to make it available to use in driver scripted expressions. This means that we can use a new function in the driver expression as follows :

drv_delay(<frame>, <attribute>, <delay>, <value>)


Where frame is the current frame (so we can detect frame change for handling the delay), attribute is a name for this 'delay queue' - each property will need to be given a unique name so that blender knows which one we are referring to), delay is how many frames the 'queue' should buffer, value is the actual value that we want to delay.

To use it, set up the driver Scripted Expression as something like :

drv_delay(frame,"cube_y",10, var)


This sets up a delay queue named 'cube_y' (for the y-coordinate of the cube) with a delay of 10 frames. var is the value being delayed. The function will essentially return the var value passed in 10 frames ago.

To demonstrate, here's an example with an Empty moving in the scene, with a Cube delayed by 10 frames and a Sphere delayed by 15 frames. The queues are automatically reset at frame 1 so the motion can restart afresh.

Blend file included

• Thankyou for your answer, I am giving you the tick for the answer and level of detail, thanks heaps for this. :) I will have a play with this to see what needs to happen and toy around with your blend file. – ToxsickcitY May 16 '18 at 6:36

Maybe you can use an Empty, parented to your moving object, with "slow parent" activated (in Object/relation Extra) and an offset of 5 frames. Then drive the empty instead of the moving object.

• Thankyou Kindly for an answer, I will try this. I wanted to give you the tick, but this other answer deserves it due to the details and effort they put into it. Cheers. – ToxsickcitY May 16 '18 at 6:28