1
$\begingroup$

It's possible to modify most of an object's properties arbitrarily in a driver.

For example, the below driver, when placed on an object's X location transform, will copy that object's Y location to its Z location on every frame:

[0, self.location.__setitem__(2, self.location[1])][0]

Is there a known way to do the same when the property that is to be modified belongs to another driver?

E.G. The below code works to set the target of a variable on the driver of an object's X location when evaluated in the console, but not when evaluated in a driver on its rotation channel:

[setattr(self.animation_data.drivers.find('location', index=0).driver.variables["var"].targets[0], 'id', self),0][-1]

$\endgroup$
3
  • $\begingroup$ Hm. Setting constraint properties from inside the driver doesn't work either, and for that matter, changing .location affects .matrix_world but doesn't actually affect .location... It seems that evaluation and thus assignments for drivers are probably done in a restricted context that gets used to update matrices and such used for display/rendering, but cannot manually affect scene data. $\endgroup$
    – Will Chen
    Mar 5, 2021 at 17:28
  • $\begingroup$ I don't think there's any restricted context, and since you're already hacking (not really using drivers like you're supposed to), you should be able to do pretty much anything - though you might be better off using an autorun script than drivers like that. Also, maybe the driver appears not to work, because it's being evaluated after the driver it modifies has already been evaluated (so-called race condition)? $\endgroup$ Mar 5, 2021 at 17:33
  • $\begingroup$ @MarkusvonBroady The first example driver I posted affects .matrix_world, but not .location, so there does seem to be some separation in how drivers are evaluated that restricts what they can affect. (It's changes to .location presumably get used by Blender to compute .matrix_world, but don't directly make it to the scene data.) I fully expect race conditions on single frames with this abuse, but I still should be able to see the changes in the UI or Python console if they're actually working. $\endgroup$
    – Will Chen
    Mar 5, 2021 at 17:58

1 Answer 1

1
$\begingroup$

self in a driver is not the original object you as a user operate on; it's an evaluated copy instead. In order to access the original object so the changes to it aren't discarded, either use a full path, or original property. So your example:

  • [setattr(self.animation_data.drivers.find('location', index=0).driver.variables["var"].targets[0], 'id', self),0][-1]

becomes

  • [setattr(self.original.animation_data.drivers.find('location', index=0).driver.variables["var"].targets[0], 'id', self.original),0][-1]
$\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.