How can I use a driver for multiple objects?

I made this little easy animation where a barrier opens automatically, if the car is near enough. I realized it with a distance driver.

Now I would like to add another car, where the barrier should open too. Is there a way to add more objects to a driver or how would you realize this?

My driver settings:

• Hello, I don't really see any reason for the downvote... could you post a screenshot of how you setup the driver for the barrier ? You can use several variables for each driver, you just have to set the correct expression afterwards Feb 6 '21 at 15:39
• thanks, i do not see any reason too...but some people... ;) of course, i updated it Feb 6 '21 at 15:40

If your driver is: max(0, min(pi/2, 2-abs(v1))), where v1 variable points to the car's location component of the axis perpendicular to the gate, then you already use max which is the method to take the bigger out of two (or more) values.

So you can calculate the bar's rotation for all cars on the scene, and pass each to the max function so the bar is always as low as the closest object in the equation allows it to be. Therefore, the driver becomes max(max(0, min(pi/2, 2-abs(v1))), max(0, min(pi/2, 2-abs(v2))))

In your case you have to add distance2 to have a distance of the second car to the gate. Then you apply the above advice with max: max(pi / 2 + (abs(distance/15) < 0.8) * (pi * 3/4 - abs(distance / 5)), pi / 2 + (abs(distance2/15) < 0.8) * (pi * 3/4 - abs(distance2 / 5)))

• i just didn't know i can add more input variables....i have to learn so much!! thank you! Nice barrier by the way...!!! ;) Feb 6 '21 at 15:56

You can add as many (maybe not, but at least several dozens) variables as you wish.

In the driver editor, click on Add Input Variable and choose your second object. In my case, I used a suzanne and a cylinder. Set up the distance variable exactly as for the first object.

Mind the name of the variables; it is important for later.

Then it is just a matter of modifying your expression to take the new variable into account. In your case, you want the expression to detect the closest one, that is to say the smallest variable, since the variables represent the distance of each object to the barrier.

The expression then becomes:

pi/2 + (min(suz,cyl/15)<0.8)*(pi*3/4-min(suz,cyl)/5)


Side note: You can ditch the abs. Distances are (normally) always positive numbers.

Result:

• Thank you!!!!!!!!! Feb 6 '21 at 16:03
• Have fun with drivers, they're really powerful :) Feb 6 '21 at 16:10
• i have! ;))) thank you!! Feb 6 '21 at 16:31

Using the driver depsgraph.

You can create a driver method, and pass the gate object and the depsgraph to it: How to use different types of data blocks for driver variables?

You could add each car object as a matrix, or distance from the gate object variable. However, instead you could pass the depsgraph and look through it for objects that match a criterion.

This way, to have a car considered in the driver, you only need to give the object a custom property named "prop".

Here is a test script. A driver is added to the property of the gate.

import bpy

def test(self, locals):
dg = locals['depsgraph']
for o in dg.objects:
if o.get("prop"):
print(o.name)
print(self.matrix_world.translation - o.matrix_world.translation)

return -1 # A simple value to indicate working

bpy.app.driver_namespace["test"] = test


Any object in the depsgraph that has a custom property named "prop" is considered a car and the distance to the gate is printed to the console. Use it to make the angle calculation desired

• Sorry for my laziness as I haven't tested it, but I think instead of checking for a particular property, you could also check for a particular name, e.g. if o.name.startswith('car') Feb 6 '21 at 18:19
• Defintely the most scalable answer ! Would there be a noticeable impact on performance in a scene with thousands of objects ? Feb 6 '21 at 21:11
• @Gorgious Absolutely. You could, however, create a list of objects that satisfy the criteria, calculated only once (only when you run the script), by putting this line before def test...: cars = [o for o in dg.objects if o.name.startswith('car')]. Now, you would iterate over this short list of cars instead of a long list of all objects in the scene. Feb 6 '21 at 21:41