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

Link: https://youtu.be/s78ClbPBHNM

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:

Enter image description here

  • 1
    $\begingroup$ 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 $\endgroup$
    – Gorgious
    Feb 6 '21 at 15:39
  • $\begingroup$ thanks, i do not see any reason too...but some people... ;) of course, i updated it $\endgroup$
    – Chris
    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)))

  • $\begingroup$ i just didn't know i can add more input variables....i have to learn so much!! thank you! Nice barrier by the way...!!! ;) $\endgroup$
    – Chris
    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.

Enter image description here

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.


Enter image description here

  • $\begingroup$ Thank you!!!!!!!!! $\endgroup$
    – Chris
    Feb 6 '21 at 16:03
  • $\begingroup$ Have fun with drivers, they're really powerful :) $\endgroup$
    – Gorgious
    Feb 6 '21 at 16:10
  • $\begingroup$ i have! ;))) thank you!! $\endgroup$
    – Chris
    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.

Enter image description here

import bpy

def test(self, locals):
    dg = locals['depsgraph']
    for o in dg.objects:
        if o.get("prop"):
            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

  • $\begingroup$ 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') $\endgroup$ Feb 6 '21 at 18:19
  • $\begingroup$ Defintely the most scalable answer ! Would there be a noticeable impact on performance in a scene with thousands of objects ? $\endgroup$
    – Gorgious
    Feb 6 '21 at 21:11
  • $\begingroup$ @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. $\endgroup$ Feb 6 '21 at 21:41

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.