1
$\begingroup$

Im working on a little project that uses drivers... I have used them extensively but Im failing to find a solution for this problem. In this project I wont use scripts. Also, this is not on BGE, but on the regular viewport.

Im trying to make a driver expression on an empty0 so that it's X location is added by 1 every time some other event happens. For example, if a cube location goes from 0 to 1, add+1 to empty0 once. But this must work on runtime, 24fps.

So this is the problem: driver expressions are little pieces of code that are run every frame change, therefore every time I do something like:

"add +1 to variable1 if some other variable2==1"

it doesn't do it only once, it will check 24 times a second if the variable2==1 and will add +1 to variable1 24 times in a second. I wanted it to only add +1 one single time every time the cube goes to x==1. If I move the cube back to zero, nothing should happen, If I move the cube back to 1 again, it should add+1 to empty0 xloc one more time only, until I repeat the process

If drivers had a "While loop" to check "while variable2==1" before making the addition to variable1, it would solve the problem. But I don't think there is, and I cannot think of another way of simulating a "while" using other drivers and tricks.

The core of the problem is the fact that a driver is being run 24 times a second and I wanted to add a simple +1 to x location of an object just once every time a cube location =1.

Maybe someone here has an idea of how to solve it...

Heres a blend file as example of the problem:

$\endgroup$
4
$\begingroup$

  1. Add a property to keep track of the drivers previous value, after adding the location driver.
  2. The update order of the drivers will have exactly one update/frame, where the new location of the driver isn't copied to the custom property.

(I will add more details later, if needed.)

Minor point
The self.location[0] with itself as a driver is not very elegant. Use a shape key if you want to have a visual indicator of 0 and 1 as in the example file.
Also use the Transformation Constraints instead of the channel locks, since the channel locs won't stop changing of the number via the transform (N) panel.


Changing the property every full second

You can check for full seconds with frame%24 == 0.

Expression: var if frame%24 != 0 else var+1 if var1==1 else var with var = empty.y and var1 = cube.x as in the original demo file.

Unraveled, this is:

# do nothing (value = var) for 23 of 24 frames
if (frame%24 != 0):
    return var
else:
    # on every 24th frame (frame%24 == 1) check for the condition
    if (var1 == 1):
        return var + 1
    else:
        return var
$\endgroup$
  • $\begingroup$ Thanks for the idea! But like I said, this should work independently of scripts. I was looking for a solution inside the own driver workflow. Also, the fact that it is being checked 24 times a second or whatever the fps of the scene is, should be irrelevant, since the main problem is the fact that multiple checks are happening while I wanted a single action (yloc+1) to happen every time the cube moves to 1. $\endgroup$ – Arkhangels Apr 17 '18 at 22:55
  • 2
    $\begingroup$ Just in case it isnt clear, is not a script. The first line (0 if frame == 1 else var if frame%24 != 0 else var+1 if var1==1 else var) evaluates as the driver expression in place of your previous expression. $\endgroup$ – Leander Apr 18 '18 at 6:53
  • $\begingroup$ @Arkhangels, I think I understood the question now. Could you checkout the newly added file. Is this what you intended? $\endgroup$ – Leander Apr 18 '18 at 9:24
  • 1
    $\begingroup$ Small note, recommend using abs(ob.location.x - 1) < TOL is a safer test for float equivalence. $\endgroup$ – batFINGER Apr 18 '18 at 11:02
  • 1
    $\begingroup$ Also, batFINGER what TOL means? I guess its some kind of limit? Anyway I tested your solution adapted for drivers: abs(self.location[0] - 1)<0.5 for example and it indeed worked like a charm, thanks for the idea! $\endgroup$ – Arkhangels Apr 18 '18 at 18:30

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.