0
$\begingroup$

Setting a Target Object for a constraint is fairly straight forward:

path = bpy.data.objects["Nurbspath"]
bpy.data.objects["Armature"].pose.bones["Bone"].constraints["Follow Path"].target = path

I'm still very new to this and I can't figure out how to do the same thing for a driver. Specifically I would like to be able to set a the Target Object for a specific variable of a specific Driver from the console. I think it would go something like this:

path = bpy.data.objects["NurbsPath"]
bpy.data.objects["Armature"].animation_data.drivers.driver.driver.variables.var["var"].targets.driver_target.ID = path

But as far as I can tell drivers don't have names so how does one specify them?

The python tooltip isn't particularly helpful either...

bpy.data.objects["Armature"] ... id

Thanks for your assistance.

$\endgroup$

2 Answers 2

1
$\begingroup$

Working with drivers in Python isn't necessarily fun, unless you also create them directly from your script. If you do that, you can catch the driver objects as return values from the creation function, and use that object to create variables, set targets, and whatnot. Here is a quick example for how to do this:

import bpy

# get the objects from the scene
path = bpy.data.objects.get("NurbsCurve")
arm = bpy.data.objects.get("Armature")

# if both exist, create the driver
if path and arm:
    print('Objects exist, continuing by adding driver')

    # create a driver for all location channels
    drv_x, drv_y, drv_z = arm.pose.bones['Bone'].driver_add('location')

    # set the driver type to MAXIMUM_VALUE
    drv_x.driver.type='MAX'

    # create a variable to control something
    var = drv_x.driver.variables.new()

    # set the target object to the NURBS path
    # note that targets is a list, depending on the driver type more than one value
    # could be required
    var.targets[0].id = path

    # set the target property to the x location of that path object
    var.targets[0].data_path='location.x'

Note that I'm also unpacking the list to drv_x, drv_y and drv_z. This is just a way of naming the three driver objects directly at creation time. If you catch the result in one object called drv, you can access the driver for the X location by using an index: drv[0].

Regarding the Python Tooltip, the line above the one you quoted is actually more helpful: It says DriverTarget.id. This tells you that the object needs to be of type DriverTarget, then you'll find an id property on it. var.targets[0] is of such a type.

$\endgroup$
3
  • $\begingroup$ Thank you very much, this is really helpful. I find it interesting that it's easier just create the driver with the script as opposed to modifying it. I'll have to play around with it all a bit more. With respect to the python tooltip, I meant in comparison to the tooltip you get from the constraint target, which gives you the full path(?). $\endgroup$
    – BlenderBro
    Commented Mar 5, 2017 at 15:52
  • $\begingroup$ @BlenderBro I'd also wish the data path for certain tooltips would not be abbreviated in some cases (hence the ... inbetween), but that's because the data path is becoming VERY long. $\endgroup$
    – aliasguru
    Commented Mar 5, 2017 at 16:05
  • $\begingroup$ @BlenderBro It's easier because you get a unique reference to the object, as opposed to somehow search for the correct one. Much less prone to errors later on, as you can be sure to have the right thing in hand. I'd assume it also runs faster performance-wise. At least that's the case in other situations, like generating new objects using myNiceOBJ = bpy.data.objects.new(name, object_data) instead of bpy.ops.object.primitive_xxx_add() and then trying to locate the thing using bpy.context.object. $\endgroup$
    – aliasguru
    Commented Mar 5, 2017 at 16:11
0
$\begingroup$

You'll want to use .find(data_path, index=index) on Object().animation_data.drivers, to avoid having to remake the driver.

data_path is the RNA path of the driven value, relative to the Object(). index is the driven index for array/vector properties.

So, for example, to change the target of a variable on a driver which controls an object's Y location transform channel, you'd do:

YourObject.animation_data.drivers.find('location', index=1).driver.variables["YourVariableName"].targets[0].id = NewTargetObject

Note that the AnimDataDrivers.find() is documented as performing a linear scan, so it's probably equivalent in performance to manually checking .data_path and .array_index on all drivers until you find the right one.

$\endgroup$

You must log in to answer this question.

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