Wiggle, how to use the output values?

Moderators: Disciple, zlovatt

Post Reply
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

Hi, so here is my problem:

Code: Select all

w = wiggle(12,50);
x = timeToFrames(time);

if (x % 2 == 0)
    {
        w;
    }
else
    {
        w.valueAtTime(time-.04);
    }
After Effects tells me that w.valueAtTime is not a function. But when I use the position (for example) of another layer with the wiggle, my code becoming:

Code: Select all

x = timeToFrames(time);

if (x % 2 == 0)
    {
        thisComp.layer("Layer 1").transform.position;
    }
else
    {
        thisComp.layer("Layer 1").transform.position.valueAtTime(time-.04);
    }
And this works just fine. So I think there is a way to get the values of my wiggle inside my first expression, but I do not get how to do it.
User avatar
CodingAe
Posts: 21
Joined: August 30th, 2017, 8:35 pm
Location: Detroit, Mi
Contact:

I'm not completely sure what you are trying to do, but this will make the first code work...

Code: Select all

var x = timeToFrames(time);

if(x % 2 === 0){
  wiggle(12, 50);
} else {
  thisComp.layer("Layer 1").transform.position.valueAtTime(time-.04); 
}
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

Hum, I think I did not explain it right. I created this piece of code to have my animation moving at a step of two frames in a comp at 25fps.

Code: Select all

var Prop = transform.position;
var x = timeToFrames(time);

if (x % 2 == 0)
    {
        Prop;
    }
else
    {
        Prop.valueAtTime(time-.04);
    }
And this works fine for me. As long as I do not have any other expression already in place: as soon as I add.wiggle(12,50) to "transform.position" I get an error.

I would like to be able to apply my script even if there is previously a loop Out or any kind of expression already over the property.
User avatar
CodingAe
Posts: 21
Joined: August 30th, 2017, 8:35 pm
Location: Detroit, Mi
Contact:

That's weird, so what you are saying is that wiggle is not working at all. If you are trying use wiggle for the position value that's in the same layer then just use wiggle() without adding transform.position and it will work the same as writing transform.position.wiggle(). In theory since valueAtTime returns a number or an array, adding wiggle to valueAtTime should work, but it did not work for me either. One thing you can do (even though it's more work) is...
1. Duplicate the layer.
2. From the duplicate layer expression menu pick whip the property that has the valueAtTime code and add wiggle() at the end of the code.
3. In original layer turn the visibility off or put opacity to 0.
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

When I write:

Code: Select all

w = wiggle(12,50);
x = timeToFrames(time);

if (x % 2 == 0)
    {
        w;
    }
else
    {
        w.valueAtTime(time-.04);
    }
   The wiggle works just fine in the first case but the error come up in the second case.

   I think it's the same kind of problem if you want to add a loopOut() over an animation with a wiggle().

   What I did is using the point of control from the effect for expression, applied my wiggle on it then use my expression over the property using this point of control instead of the property itself, and this work.

But I want to find a way to write it in only one expression without adding other element.

PS: I'm french, so my english is far from perfect and it makes it more difficult for me to be understandable, sorry about that.
User avatar
CodingAe
Posts: 21
Joined: August 30th, 2017, 8:35 pm
Location: Detroit, Mi
Contact:

Sorry for the late respond, but for these last two days I couldn't think of any way to use wiggle with another method like valueAtTime. The reason why I believe that After Effect is saying that "valueAtTime is not a function" is because After Effects is saying that there is error using valueAtTime. I believe that valueAtTime is looking for a property object that had a number or an array and while wiggle does output a number or an array however it is not a property object. For that reason After Effects have to throw an error using wiggle before valueAtTime. In short, I believe (not 100% certain) that there is no way to add wiggle or any other method before valueAtTime because valueAtTime will be searching for a property object. Sorry I don't think I was that helpful, hopefully somebody could jump in this post and prove me wrong.
beginUndoGroup
Posts: 81
Joined: November 27th, 2012, 6:41 am

Try this:

Code: Select all

if (timeToFrames(time)%2 ==0){
    wiggle(12,50);
    }
else{
    wiggle(12,50, 1,0.5, time-0.04);
    };
wiggle(freq, amount, octave, multiplier, time);

It's a method for properties, and it outputs the same kind of things as the property's value (number, array of numbers, etc).
So you can't chain wiggle(freq, amount).valueAtTime(t)
(numbers, arrays, etc dont have a valueAtTime method).

Xavier
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

Hi,

Sorry I've been so long to answer.

@ beginUndoGroup: I tried the code you propose. Unfortunatly, it does not do the trick, the position is not kept, the object moves everyframe.

I checked the type of "thisComp.layer("Rouge sombre uni 1").transform.position.wiggle(12,50)", and it is an object, not an array like I expected. Now this object only has two properties which are x and y of my object. From  there I tried putting it in a variable like this:

Code: Select all

XY = thisComp.layer("Rouge sombre uni 1").transform.position.wiggle(12,50);
Position = [ XY[0] , XY[1]]
But this still won't work with the valueAtTime() method.

I really don't get what I do not give to this method for it to work. It is the same if you want to loopOut() a wiggle or whatever. I guess that when you use thos methods, the nature of the object is modified but how? And how to get those infos back, I do not know.
beginUndoGroup
Posts: 81
Joined: November 27th, 2012, 6:41 am

I had not tried my code when i posted, and i just did: it works for me. The solid animated with this expression moves every second frame, and holds it position otherwise.
I don't know why it's not working for you.

Side note: Arrays are objects : if a is an array, (typeof a) is : 'object', and (a instanceof Array) is true.
So, "thisComp.layer("Rouge sombre uni 1").transform.position.wiggle(12,50)" is just an array, holding 2 numeric entries ("0" and "1").

Xavier

Edit : Make sure that the comp frameDuration is indeed 0.04, else it cannot work. Or simply replace 0.04 by thisComp.frameDuration in the expression.
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

Hi,

So sorry, you are right! This code works just fine for the wiggle. I do not know what I did... Thanks!

I still do not succeed to make this work with a loopOut() but that is nice first step :D

Thanks for the side note! I really did not know that. But if it is just an array, why can't I apply a valueAtTime to this? Do you have an idea?

 I think I'll end up searching for another way to do what I want without the valueAtTime function even if it seemed the best way at first.
Chacal
Posts: 10
Joined: November 29th, 2017, 1:28 am

Just to update this thread.

Instead of using the output values of a wiggle, I finally discovered the posterizeTime() function, which does exactly what I needed.

Thanks for everybody trying to help.
Post Reply