1
$\begingroup$

I need to dynamically control some properties, of which i have the data_path, in every frame of the animation using a python script. The obvious solution is to create a driver on the property, but I would like to still be able to edit the property (to set a fixed offset, basically).

Also, I want this rig to work with all (or most of) the object's properties, so I can't use an empty to store the drivers, because the empty might not have that property (also, is there a way to set the value of a property only knowing its data_path? that would solve everything...).

EDIT

As an example, I would like to control, for every frame of the animation, the obj.location of my current object by using a python function pyFunction(self, target), that I declare in the script. To do that I need to create a driver with the pyFunction(self, target) function in the expression field. So far so good. However here I got stuck:

1) If I create the driver directly on the object's location property, I can't then move the object with the "G" hotkey or with the arrows (I could create 3 custom properties and point to them in the driver, but it's not very user friendly to change the object position using 3 separate sliders, hidden in the Custom Properties).

2) If I create the driver on a custom property, then I don't know how to change the location property: the driver controls the value of the Custom Property it is applied to, but not the value of the property I want to change. The main problem is that I don't know which properties are being targeted: in my script I have the data_path of the properties I need to control (that I get from the object's fcurves), and I couldn't find anywhere a setValue(data_path) function or whatever that allows me to change the value of a property in python, only knowing its data_path. For example, if I need to control the influence value on a modifier of that object, I don't know how to make its value change with the Custom Property value, without having to add another driver on the desired property , which is the (1) problem all over again (or how to directly change its value inside the pyFunction)

To control the rotation.x i need to create the driver, but then I can't manually rotate the object on the x axis with the "R" key (to create an offset that could be used to manually introduce variations in the object placement)

In the screenshot, to control the rotation.x i need to create the driver, but then I can't manually rotate the object on the x axis with the "R" key (to create an offset that could be used to manually introduce variations in the object placement), and from the custom property obj["prop"] I don't know how to change the rotation value (using obj.rotation.x or obj.rotation[0] in the pyFunction is not a good solution, because I only know the data_path of the property and with most of them obj.data_path doesn't work).

Also, don't worry about the error in the driver, pyFuntion is currently an empty function, mine works as expected, but it's very long and i didn't want to make things more complex than necessary...

Can you guys help me figure it out?

$\endgroup$
  • $\begingroup$ Have you ever entered a custom property on an object? $\endgroup$ – atomicbezierslinger Mar 26 at 18:34
  • $\begingroup$ Also if the offset is determined by each object you may be able to use [self] to refer to a custom property on the object through some Python and bpy. $\endgroup$ – atomicbezierslinger Mar 26 at 19:20
  • $\begingroup$ It would be useful to know how much Python experience you have so that I can simplify explanation in some cases. Months, Years? $\endgroup$ – atomicbezierslinger Mar 26 at 19:23
  • $\begingroup$ @atomicbezierslinger something like 5 or 6 months $\endgroup$ – Tareyes Mar 26 at 20:12
  • $\begingroup$ As a comment note 📝 I must say I view your work as a heroic battle ⚔. Blender and Python learning challenges. It reminds of the first month I saw Blender and cursed it to myself because either BSE did not exist or I was not aware of it. $\endgroup$ – atomicbezierslinger Mar 26 at 22:03
2
$\begingroup$

Custom Properties and Delta Transformation

enter image description here

Delta Transform Location X component with Driver cooperate nicely with regular Location. You may grab and move object with g. Formula is in tooltip. See Arrow. Image above. Emphasizing difference between regular object Location and Delta Location.

I am trying to prioritize various issues you have in your question above. So somethings I may say you might already know. Same as in any candidate answer.

You may also create a Parent/Child relationship in Blender. Two objects selected and then Control P your object to another object to combine locations and have independence.

https://www.youtube.com/watch?v=kq3Ja-nNv7Q

For the near future ... I suggest you use the datapath only when self is data in the object panel, in a Python Script. Self does not always refer to an object as displayed in the object panel. Self might refer to a Modifier or Constraint or Material Setting or Fluid Setting ... depending on the panel with the driver.

The Blender Python Console Window and the OS owned text Console window are two different windows.

You wrote [pyFunction(self, target)]

In your function please add

print(type(self))

to see the text name in the Text Console Window. The Python Console provides a python environment in a Blender Window. Text Console can show print results from a Script and may be provided by the OS. Menu / Toggle Console Window.

A driver on a location or delta location can refer to another custom property of a different object. Final location is a combination of location and delta location. Thus if driver controls delta location, then (regular) location can be be free for UI interaction control.

The same can be said analogously of rotation. Other techniques exist.

Allow the driver to refer to a different custom property value. Indirection can solve or introduce any problem.

Custom Properties have all the conveniences of other standard values of Blender. They are keyframe capable.

enter image description here

Display of Custom Properties. Image Above. Click the Add button, enter value. Please know there are default limits which can be edited. Click the edit button.

enter image description here

Driver referring to custom property with offset as part of the expression or formula. Here I entered two properties on one object for purposes of less image editing. You have more freedom than that.

Any object can hold custom properties which is similar to Python Dictionary. See [custom properties] which appear in the panel. When the property is numeric for example it can be keyframed. The keyframed property can be seen in the graph editor and manipulated like any other graph window curve. The Driver can refer to those properties. Custom Property CRUD Create Reference Update Delete is possible. If the user interface is inadequate perhaps the creation of a custom property can be another question.

Keep in mind Python functions can be registered for access in drivers. This can explained more fully in another question or search.

And the driver can access the custom property by object name and property name or path.

Please note that it may be useful to create an independent object to hold custom property values. Blender can complain with messages in the console window when it deems references for a cyclical dependency. Blender may be a arguable too strict about that. But see the messages in the console might interfere with your needs.

A constraint can copy the location of another object if desired but is more dominating. I would test carefully to see the differences.

$\endgroup$
  • $\begingroup$ Thanks for the answer, but that's not my question (sorry, i may have not explained myself clearly, my bad): I know how to use drivers and custom properties, but I don't know how to use them in my case. I have edited my question to explain myself better, sorry for the confusion... $\endgroup$ – Tareyes Mar 26 at 20:10
  • $\begingroup$ Thank you very much man! Very appreciated! I didn't think about the delta transform... I've set this question as solved. However, I have one following question: if "self" in the driver expression doesn't always indicate the object, but can indicate modifiers etc..., how can i get the object? For example, self could be a subsurf modifier, but i need to get the object, because in my pyFunction I need to access another Custom Property on the object itself. I even tried getting the name of the object from the driver item itself, but I can't get my head around it... $\endgroup$ – Tareyes Mar 27 at 8:28
  • $\begingroup$ @Tareyes self.id_data will return the ID object. Eg if the driver is on a modifier, self is the modifier, self.id_data is the object $\endgroup$ – batFINGER Mar 27 at 8:49

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.