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

seedRandom - How to get different values every time I preview

New Here ,
May 17, 2017 May 17, 2017

Copy link to clipboard

Copied

Hi,
So iv'e used Dan Ebberts script to randomly position a layer across time.
My problem is that every time I preview the comp - my layer traverses the exact same path.
The random numbers generated the first time are regenerated every time I preview the comp. I would like to have a different value for each position every time I preview the comp.

Here is Dan's script:

segMin = .7; //minimum segment duration
segMax = 1.7; //maximum segment duration
minVal = [0.1*thisComp.width, 0.1*thisComp.height];
maxVal = [0.9*thisComp.width, 0.9*thisComp.height];

end = 0;
j = 0;
while ( time >= end){
  j += 1;
  seedRandom(j,true);
  start = end;
  end += random(segMin,segMax);
}
endVal =  random(minVal,maxVal);
seedRandom(j-1,true);
dummy=random(); //this is a throw-away value
startVal =  random(minVal,maxVal);
ease(time,start,end,startVal,endVal)

TOPICS
Scripting

Views

5.8K

Translate

Translate

Report

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
Enthusiast ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

You can get a different random value for each preview/render by changing the random seed to use a value that's variant with clock time.

For example:

segMin = .7; //minimum segment duration
segMax = 1.7; //maximum segment duration
minVal = [0.1*thisComp.width, 0.1*thisComp.height];
maxVal = [0.9*thisComp.width, 0.9*thisComp.height];

end = 0;
j = 0;

randSeedBase = Date.now()
while ( time >= end){
  j += 1;
  seedRandom(j+randSeedBase,true);
  start = end;
  end += random(segMin,segMax);
}
endVal =  random(minVal,maxVal);
seedRandom(j-1+randSeedBase,true);
dummy=random(); //this is a throw-away value
startVal =  random(minVal,maxVal);
ease(time,start,end,startVal,endVal)

Votes

Translate

Translate

Report

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 ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

Thank You. There is a new problem - The seed seems to be seeding anew every frame so the layer is jumping around rather than the smooth motion I had before...Any thoughts?

Votes

Translate

Translate

Report

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
Enthusiast ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

Sorry, I was thinking this was a script rather than expression. My brain is on the fritz this morning

Because it's an expression it has no state outside of each frame it's evaluated for during a playback/render. Which means to get consistent random behavior (smooth motion for your purposes), the expression has to be designed to produce the same random numbers for each invocation, which is how Dan correctly wrote the script. What you're asking is that you want the entire set of random numbers to reset between different renders/playbacks but unfortunately there is no automatic way to do this because the expression has no way to distinguish between being told to draw one frame vs another for a given render/playback vs drawing a frame for a different render/playback.

Although there is no automatic way you can manually cause the expression to use a different set of random numbers by putting a slider control on your layer, adding the control's value to the seedRandom() calculation, and then changing the slider's value manually whenever you want to cause a new random motion path (ie, between renders). Here are the steps:

  1. Add an expression control slider to your layer. (Go to Effects & Presets, type "slider" in search box, then drag "Slider Control" in the search results to your layer
  2. Change the calls to seedRandom() to include the value of the slider control (see code below)
  3. For each new render/preview, manually change the value of the slider to change the random path of your animation

segMin = .3; //minimum segment duration

segMax = .7; //maximum segment duration

minVal = [0.1*thisComp.width, 0.1*thisComp.height];

maxVal = [0.9*thisComp.width, 0.9*thisComp.height];

end = 0;

j = 0;

while ( time >= end){

  j += 1;

  seedRandom(j+effect("Slider Control")("Slider"),true);

  start = end;

  end += random(segMin,segMax);

}

endVal =  random(minVal,maxVal);

seedRandom(j-1+effect("Slider Control")("Slider"),true);

dummy=random(); //this is a throw-away value

startVal =  random(minVal,maxVal);

ease(time,start,end,startVal,endVal)

Votes

Translate

Translate

Report

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 ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

Thanks again. I get the logic I think. There is still a problem. Iv'e dragged the slider control effect to the layer and the script doesn't seem to call it. The layer remains stationary and I get an error the likes of "position of layer 1 in comp 'a', effect named 'Slider Control' is missing or does not exist".
I then added a keyframe on the slider control effect and it's script looks like this:
effect("Slider Control")(1) which I guess is the initial value. Still not working...

Votes

Translate

Translate

Report

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 ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

Sorry! It's working. I guess I mistepped somewhere so I did it again. Thanks so much for your help....:-) I learned something new as well!

Votes

Translate

Translate

Report

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 ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

One last thing. I hope it's ok to continue on this thread. Is there a way I can limit the script to an x amount of frames. I'd like to after let's say 100 frames for the layer to stop moving around and I would like to give it a final non random value for position which it would ease into from the last random position...

Votes

Translate

Translate

Report

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
Enthusiast ,
May 18, 2017 May 18, 2017

Copy link to clipboard

Copied

Sure. If you want the animation to stop after 100 frames, change the while loop line to this:

while ( Math.min(time,framesToTime(100)) >= end){

Votes

Translate

Translate

Report

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 ,
May 19, 2017 May 19, 2017

Copy link to clipboard

Copied

Thanks:-) One last thing -
Lets say i ran the anim for 100 frames or whatever I put in the while loop. I would like to make the last position of the layer be the first position of a new layer. How do I get the value of the last position of that layer?

Votes

Translate

Translate

Report

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
Enthusiast ,
May 19, 2017 May 19, 2017

Copy link to clipboard

Copied

Assuming the original layer's name is "OrigLayer" and you want its position value the 100th into the entire composition (from start of comp):

thisComp.layer("OrigLayer").transform.position.valueAtTime(framesToTime(100))

Let's say you want the same thing but instead of the 100th frame from the start of the comp you want it the 100th from the start of the layer. This will be the same as start of comp (above expression) if layer starts at 0:00 into the comp but different if the layer starts later into the comp (ie, it's in-point is not 0:00)

thisComp.layer("OrigLayer").transform.position.valueAtTime(framesToTime(100) + thisComp.layer("OrigLayer").inPoint)

Votes

Translate

Translate

Report

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 ,
May 19, 2017 May 19, 2017

Copy link to clipboard

Copied

LATEST

Awesome. Thx so much...

Votes

Translate

Translate

Report

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