ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

If, Then, Stop Until... or something like that

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Royce Jennings
If, Then, Stop Until... or something like that
on Feb 16, 2019 at 12:02:05 am

Hello!

I've tried for hours searching so many things, but have come up with nothing. What I'm trying to do is select a random number *one time* when a condition is true, then only generate a new number after the condition is false, then *newly* true again.

So I've got this on the Rotation parameter of a layer:

seedRandom(0,true);
boom = effect("Boom")("Slider");
if(boom > 3){seedRandom(boom,true)};//If boom slider is greater than 3, pick a random number.
pick4 = Math.round(random(3));//Generate random integer between 0 and 3.
if(pick4 == 0){0}else if(pick4 == 1){90}else if(pick4 == 2){180}else if(pick4 == 3){270};//Rotate to 0,90,180, or 270, depending on the random number.


So I want one of 4 rotation options (0,90,180, or 270) to be randomly selected when my slider goes above 3, but I don't want new rotations every frame while the slider is over 3 (which it currently does). I want it to hold the rotation until not only the slider dips down to *less than 3* (lol <3) but also until it goes over 3 again, THEN pick a new rotation and hold it, etc. So like a gun, one shell comes out when you cock it back, then it has to go both forward and back again before you get a new shell.

I don't know if it's a matter of using a variable to save the state until (boom < 3) again, or if it's somehow "holding" things until < 3.... I even tried posterizing time to freeze things, but it doesn't quite work right, and is clearly just a hack.

Any ideas? Thanks for any feedback.

seedRandom(0,true);
boom = effect("Boom")("Slider");
if(boom > 3){seedRandom(boom,true)};//If boom slider is greater than 3, pick a random number.
pick4 = Math.round(random(3));//Generate random integer between 0 and 3.
if(pick4 == 0){0}else if(pick4 == 1){90}else if(pick4 == 2){180}else if(pick4 == 3){270};//Rotate to 0,90,180, or 270, depending on the random number.



Return to posts index

Oleg Pirogov
Re: If, Then, Stop Until... or something like that
on Feb 16, 2019 at 1:14:10 am

My shot will be:

1) Have a "Boom" slider:


2) Have a "DC Boom" (discreet-constant) slider:

- which equals 1 if boom>3 and 0 otherwise:
effect("Boom")("Slider")>3 ? 1 : 0;

3) Have a "Delta Boom" slider:

- which equals 1 on those frames only, on which DC Boom switches from 0 to 1:
dcBoom = effect("DC Boom")("Slider");
delta = Math.max(dcBoom.valueAtTime(time) - dcBoom.valueAtTime(time-framesToTime(1)), 0);

4) Have an "Integrated Delta Boom" slider:

- which counts those switches till current time:
db = effect("Delta Boom")("Slider");

var numofSkips = 0;
for (i = 0; i<= timeToFrames(time); i++){
if (db.valueAtTime(framesToTime(i))) numofSkips++;
};

numofSkips;


5) Implement it for Rotation like this:
idb = thisComp.layer("Controls").effect("Integrated Delta Boom")("Slider")

seedRandom(idb,true);

pick4 = Math.round(random(3));
if(pick4 == 0){0}
else if(pick4 == 1){90}
else if(pick4 == 2){180}
else if(pick4 == 3){270};


Seems to work as you've described.


Return to posts index

Royce Jennings
Re: If, Then, Stop Until... or something like that
on Feb 17, 2019 at 12:34:37 am

Oleg,

Thank you so much for this in depth solution and explanation, I've learned a lot this afternoon from what you've provided! And yes, it works immaculately! I didn't know about Math.max, that's a great little tool for niche applications like this...

So the last thing I'm trying to accomplish is a slider that takes and holds the Boom value upon delta until the next delta. I have it working except for the hold; it doesn't seem to want to reference it's own value from (-1) frames ago. I have this on a slider called CurrentBoom:

boom = effect("Boom")("Slider");
dcBoom = effect("DC Boom")("Slider");
thisSlider = effect("CurrentBoom")("Slider");//Self-referential.

if(dcBoom.valueAtTime(time) > dcBoom.valueAtTime(time-framesToTime(1))){//Check to see if dcBoom just went up to 1.
boom//Make this slider the boom value.
}else{//Otherwise...
thisSlider.valueAtTime(time-framesToTime(1))//Make this slider the value it was last frame.
};

So I get the boom value on delta, but then then it goes to zero the next frame until the next delta. Are these types of self-referential calls possible?

Thanks again so much for your help! Already you've gotten my head spinning with nerdy options I didn't know I had..... :O

boom = effect("Boom")("Slider");
dcBoom = effect("DC Boom")("Slider");
thisSlider = effect("CurrentBoom")("Slider");//Self-referential.

if(dcBoom.valueAtTime(time) > dcBoom.valueAtTime(time-framesToTime(1))){//Check to see if dcBoom just went up to 1.
boom//Make this slider the boom value.
}else{//Otherwise...
thisSlider.valueAtTime(time-framesToTime(1))//Make this slider the value it was last frame.
};


Return to posts index


Oleg Pirogov
Re: If, Then, Stop Until... or something like that
on Feb 17, 2019 at 3:32:43 am

You're welcome!
The thing you see is because when self-referencing in an expression like taking "valueAtTime" of current layer it actually references to the static value. So it goes to zero because the static value (the value you get when expression is off) for "thisSlider.valueAtTime(time-framesToTime(1))" is zero. I.e. if you turn off the expression, set slider value to be, say, 13 and turn on expression again, it will now be switching to 13 instead of zero.

What you basically need is to have the time of the most recent up-skip, so you can just reference it as "boom.valueAtTime(LAST_UP_SKIP_TIME)".

For that I would suggest switching your approach to what Dan has posted below. It actually works with that LAST_UP_SKIP_TIME (well, not time but frame number technically) under the "frame" variable.

All you need is to change the last "if" expression in Dan's code to:
...
if (frame == 0){
value;
}else{
boom.valueAtTime(framesToTime(frame))
}


Return to posts index

Dan Ebberts
Re: If, Then, Stop Until... or something like that
on Feb 16, 2019 at 9:45:52 pm

Something like this should work:


threshold = 3;
boom = effect("Boom")("Slider");
above = false;
frame = Math.round(time / thisComp.frameDuration);
while (true){
t = frame * thisComp.frameDuration;
if (above){
if (boom.valueAtTime(t) < threshold){
frame++;
break;
}
}else if (boom.valueAtTime(t) >= threshold){
above = true;
}
if (frame == 0){
break;
}
frame--
}
if (frame == 0){
value;
}else{
seedRandom(frame,true);
n = Math.floor(random(4));
n*90;
}



Dan



Return to posts index

Royce Jennings
Re: If, Then, Stop Until... or something like that
on Aug 5, 2019 at 2:45:57 pm

Jeez I'm realizing I've missed this reply; I think I need to look at my notification settings. This is great. Thanks Dan, you're a legend whose thinking and coding are always at the peak of efficiency... much respect and thanks! :D


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2019 CreativeCOW.net All Rights Reserved
[TOP]