Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Trying to Create a Wiggle Effect that STAYS Where It Moves To (Instead of Always Bouncing Back)

New Here ,
Dec 13, 2022 Dec 13, 2022

For making stop-motion animation, I'm trying to alter the AE Wiggle expression (or essentially create a Wiggle knockoff) that jumps to a slightly altered position, but then stays at that position until a new randomized Wiggle coordinate comes in. So far, it isn't quite working and would love some input if anyone else out there can figure out how this would work better!

 

Why I'm Doing This: The idea here is that realistically when shooting stop-motion with an actual camera, if a paper cutout accidentally gets bumped into a slightly new position, it will probably stay there until bumped again, X number of frames later. (It won't, in other words, jump to a new spot then immediately bounce back, as the Wiggle expression has it do by default.) So I'm trying to make a more realistic-looking stop motion effect.

 

The Current Setup with Expressions: My approach has been to use valueAtTime to have After Effects read previous position values. If a new wiggle coordinate is given, the wiggling layer's position accepts that value and moves there. But if no new coordinate is given (and the randomizing function spits out a zero instead), the position is told to stay put (by accessing the previous position coordinates with valueAtTime(time-thisComp.frameDuration) and taking in those previous coordinates as the new coordinates).

 

I can't seem to get this to work more directly with Wiggle, so I've set up a Null with multiple sliders to mimic (but alter) what the Wiggle expression does.

 

Here are the first two sliders in the Null that I've called "Wiggle Sliders":

 

Slider Control > Slider  (In "Wiggle Sliders" Null):

x = Math.round(random(Math.round(random(Math.round(random(Math.round(random(Math.round(random())))))))))

wa = 40*random(x)

neg = Math.round(random())

 

if(time==0 || wa!=0)
{
if (neg==0)
{
val=wa
}
else
val=-1*wa
}

else
{
val =thisComp.layer(index).effect("Slider Control 2")("Slider").valueAtTime(time-thisComp.frameDuration)
}

 

Slider Control 2 > Slider  (In "Wiggle Sliders" Null):

 

val = thisComp.layer(index).effect("Slider Control")("Slider").valueAtTime(time)

 

 

 

Slider Control 2 just takes in what Slider Control currently has, so that Slider Control can then access Slider Control 2's previous value (because I can never get it to work when just one Slider is trying to access its own previous value).

 

The first Slider Control value is then accessed by the x-position of the layer I want to wiggle, adding or subtracting this amount from its original position value (and then uses two more sliders, 3 and 4, in the Null that do the same thing for the y-position):

 

Transform > Position  (In "Wiggle Sliders" Null):

val = [transform.position[0] + thisComp.layer("Wiggle Sliders").effect("Slider Control")("Slider"),
transform.position[1] + thisComp.layer("Wiggle Sliders").effect("Slider Control 3")("Slider")]

 

 

Problems with Execution: Generally this seems close to working...but then the sliders glitch a lot. The slider values at first successfully hold on a random value that's been spat out (ex: 0.3 or 5.7 or -9.4), but then often a few frames later they revert back to zero (which they are not supposed to). Sometimes they revert back to zero after ten frames, sometimes after two frames, sometimes right away.

 

Also, even when the slider values hold as they should, the position value of the wiggling layer does not. So far, it goes to the new position, then one frame later always jumps back to the original position (even if the inputted slider values are telling it to stay put and not go back to the original position for, say, another twenty-five frames). 

 

I'm certainly no expression expert, but this setup seems like it should work to me, so I'm awfully frustrated that it isn't working so far. Thanks in advance for any advice!

TOPICS
Expressions
2.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Dec 13, 2022 Dec 13, 2022

If you need random jumps in position and rotation to be synchronized, you could add a slider with an expression like this:

minHold = .5;
maxHold = 3;
seedRandom(index,true);
t = inPoint;
idx = 0;
while (t <= time){
  idx++;
  t += random(minHold,maxHold);
}
idx

and then this for position:

minOffset = [-10,-10];
maxOffset = [10,10];
idx = effect("Slider Control")("Slider");
seedRandom(idx,true);
offset = random(minOffset,maxOffset);
value + offset

and this for rotation:

minOffset = -5;
maxOffset 
...
Translate
Community Expert ,
Dec 13, 2022 Dec 13, 2022

Would something like this work?

posterizeTime(5);
wiggle(5,10)
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 13, 2022 Dec 13, 2022

Right. That's generally the setup I've been working with already until now (Wiggle and Posterize Time). Those generally work well...but they create an effect that's ultimately somewhat predictable and unrealistic looking to real stop motion, especially when you have twenty objects all similarly wiggling on the screen at once. My hope was for something that's less moving back and forth over and over...and instead stays in the same place for seconds at a time, then shifts to a new spot and rotation, holds there, then shifts again, all at unpredictable intervals of time. To in other words look like more organic, accidental little movements like in real stop motion.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 13, 2022 Dec 13, 2022

How about something more like this (this one would be for position):

minOffset = [-10,-10];
maxOffset = [10,10];
minHold = .5;
maxHold = 3;
seedRandom(index,true);
t = inPoint;
idx = 0;
while (t <= time){
  idx++;
  t += random(minHold,maxHold);
}
seedRandom(idx,true);
offset = random(minOffset,maxOffset)
value + offset
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 13, 2022 Dec 13, 2022

If you need random jumps in position and rotation to be synchronized, you could add a slider with an expression like this:

minHold = .5;
maxHold = 3;
seedRandom(index,true);
t = inPoint;
idx = 0;
while (t <= time){
  idx++;
  t += random(minHold,maxHold);
}
idx

and then this for position:

minOffset = [-10,-10];
maxOffset = [10,10];
idx = effect("Slider Control")("Slider");
seedRandom(idx,true);
offset = random(minOffset,maxOffset);
value + offset

and this for rotation:

minOffset = -5;
maxOffset = 5;
idx = effect("Slider Control")("Slider");
seedRandom(idx,true);
offset = random(minOffset,maxOffset);
value + offset

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 13, 2022 Dec 13, 2022

Ooooh, yes, that's looking great!

 

I've plugged it into position and tweaked it to work for rotation as well. My only remaining question would be how to then make it so that the position and rotation only change at the same times. Right now, because I've plugged them in as two separate expressions, only one changes in any given frame, the position or rotation.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 13, 2022 Dec 13, 2022
LATEST

Oh nevermind, hadn't refreshed the page. Looks like you beat me to it.

 

Thank you so much!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 13, 2022 Dec 13, 2022

AE has no way of remembering values and that's what it basicalyl boils down to. If a "dumb" change with posterizeTime() and such doesn't work, you can't possibly avoid delving into all this integration stuff to figure out what the last value/ position actually was as explained in Dan's own classic article:

 

http://www.motionscript.com/articles/speed-control.html

 

Mylenium

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 13, 2022 Dec 13, 2022

Yeah, that's the frustrating fact that I've been trying to work around. I thought I had it with these sliders, but maybe the glitchiness just can't be avoided because how After Effects isn't fundamentally built to be able to store and remember previous values...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines