ValueAtTime Expression- Adobe After Effects tutorial
Vložit
- čas přidán 24. 05. 2019
- The valueAtTime() property is one of my most used expressions in Adobe After Effects. In this short tutorial, we'll cover the basics of how it works, and how to make a simple trail with a custom delay. Do don't delay, and follow along with this tutorial!
If you have any questions just let me know in the comments.
Download this project file:
evanabrams.com/valueattime-exp...
Connect on the Internets
www.EvanAbrams.com
ecabrams
www.Facebook.com/EvanCAbrams/
EvanCAbrams
Suggest a tutorial topic: docs.google.com/forms/d/13A2e...
Google+
plus.google.com/+EvanAbrams/
10/10 tutorial. I figured this out a few months ago and it works great for so many projects
It is pretty rad. Glad you still enjoy the tutorial on it :)
GREAT TUT - thank you. I can so easily apply this to so may projects, along side other expressions I'm familiar with.
Got going within a few minutes, after hitting my head against a wall with some other tuts.
Cheers!
Evan, you explain complex concepts with so much clarity and professionalism.Thank you for what you do; it's a pleasure and a privilege to have access to the depth and breadth of your knowledge through these tutorials. I leaned heavily on your channel during an AE class I took a couple years ago, and have recently been hired to do some motion graphics. This is thanks, in no small part, to you.
While I'm here: are there any especially surprising applications of this expression, outside of time remapping?
Very useful! Many thanks. Just used it to link the complex motion of two objects together with a 1/10th second delay to make it look more random.
This lesson is incredible. Just learning expressions and the way you describe it is perfect! Thank you.
That's fantastic to hear! I hope I can make the time to create more videos like this one :)
Youre a life saver! Thank you! I really like how clearly you expained what the functions refer to :)
Love your expression videos! Like that you show how an expression can be used in different ways 👍 helpful when learning for fun
Thanks! I'm glad the extra context helps.
You are an awesome teacher! Keep up the great work
Great info and I really like the way you teach. Thanks for sharing.
I'm glad you enjoy it!
Super helpful- as usual. Just revisiting this now, as you do such a great job of of explaining these concepts :) Thanks for your valuable time!
keep up the good work Evan! would love more advanced expressions videos and generally more expression stuff
I'm working on just such a video ;) we'll see how long it takes to get it together though.
Seriously. It’s one of those areas that can never get enough attention.
1:58 wow I know it’s not rocket science, but being an AE beginner...I could never really grasp what all that meant. But you just described it so wonderfully and it all makes sense now. Two minutes into the vid and I’m already learning. That’s Evan Abrams for you! 🤝
Great explanations! Thank you!
Exactly what I was looking for..... Thanks Mr. Abrams
Thank you EC. This is a great help!
This is really works for me! And very eazy to understand the expression. Thanks a lot!
This is very helpful thank you! Also enjoyed the puns!
I appreciate the detailed explanations. I think there's a huge chance continuing from here showing some real life applications. Like, maybe a simple example of how you use it in an actual project... not that I'd expect you to give away all your secrets :) But maybe kinda like the write-on video. Personally I'm a slow learner, and I get a lot of inspiration from seeing how it's actually used and then getting into more detail with the technique.
great videos, i've watched 3 or 4 now and worth subbing
Best tutorial about this expression I ever saw! :D Thanks a lot for the good work! : ))
Thank you so much. Glad you enjoyed it!
Thank U. I did it with path property. And it worked well.
Thanks for such a great explanation
Index - 1 was the most important thing, I learned her Thanks!
Wow.. Excellent breakdown
Glad you think so!
in Abrams we trust (regarding scripting), LOVE this channel. I'm pretty sure most people would use the echo effect to get something like this and then play with the echo effect. Problem is that method is very heavy on the processor and doesn't allow you to work smoothly in real time like you are which hinders work flow. So this is deffinetly a much better method. Thanks for offering new perspectives to what's possible.
I'm glad it helps expand what is possible for people. I hope it starts you on a journey into even more expressions :)
There is a lot of value you can get for the time of this tutorial.
Many thanks. I used it to build a "spiked wheel".
This tutorial is super useful. Btw we met at NAB! I was the weirdo who said I owed my career to your tuts. If you’re ever in Seattle I owe you a beer.
I’m happy to hear it. That means a lot to me. When I hear that stuff it truly motivates me to keep the channel going.
@@ECAbrams I also got a job in motion design mostly thanks to the great content you put up haha, so thanks!
Just as a reminder for myself :D
P=thisComp.layer(index-1).transform.position;
D=thisComp.layer("Adjustment Layer 1").effect("Slider Control")("Slider")*thisComp.frameDuration;
P.valueAtTime(time-D)
Thanks! I so needed this!
Perfect explanation..
I almost skipped this one...but here I am, watching my little arrow and dots move around the screen.
Another great tutorial.
Thank's a lot!
Just last week I was wishing there was a time delay option inside the shape repeater (which would still be good to have, Adobe...) but this seems like it could solve that issue, which is nice.
This can get you close for sure :)
My one comment that I was hung up on...
When trying to reference one value in an array... (ref. X value but not Y value)
You have to do the array indexing after valueAtTime():
Don't do this:
t = thisComp.layer(index-1).transform.position[0].valueAtTime(time - x);
Write it like this:
t = thisComp.layer(index-1).transform.position.valueAtTime(time - x)[0];
Thank you Dan Ebberts for this bit of info.
Thanks Evan.
OMG THANK YOU SO MUCH!!
Thank you
Gosh I wish I have discovered this earlier! I wasted so much of my valuable time doing it myself (and failing). Thanks!
Another use - Create an animation (can be 3D cams, 3D nulls, colors, sliders, etc.) and set a key at frame 0 and at the last frame in the comp. Then, create a null and add a slider control, this will be used to drive the time remap of the comp! Simply add the expression : (valueAtTime(sliderControl)’ to whatever value you want to control. sliderControl is the slider you made on the null in the last step. Then, animate the slider and it will work just as fine remapping a video will!
Great pun!
thank you... once it sinks in, its a handy tool to know!
Happy to hear it!
this is Echo with costume shaps. it's awesome.
Hello Evan,
I think that ValueAtTime could be used to animate a follow through hair or something, could you explain if it was possible ?
Big fan, thank you for these amazing tuts
Great suggestion! I've done that a few times using a Math.sin() to generate the motion, value at time to get samples from later or earlier, and all of that driving relative puppet pin positions. But it's a great idea. Does any of that help get you started?
I have a question: How can I make stop the follower object at a certain point, not at the leader's final position? Thanks for the tutorial!
if we modify the time to be now, or now minus time, that could be a way. You might even keyframe that relationship. Does that help?
Hey Abrams I am still confused by what frameDuration means at 6:30. Could you rephrase it and why we multiply the slider control number by thisComp.frameDuration? Thanks!
frameDuration is the time in seconds that one frame lasts. So in a comp that is 24 fps for example, one frame last 1/24th of a second. Because valueAtTime understands inputs in seconds only, if you want to relate with the the value on a per frame basis you need to do this little bit of math. So if we want to get the value from 5 frames ago we want to know how long in seconds 5 frames is. We can find that number by multiplying 5 by the frameDuration. Does that make sense?
What would I need to add to the expression "var P=thisComp.layer(index-1).transform.position;
var D=thisComp.layer("Adjustment Layer 1").effect("Slider Control")("Slider")*thisComp.frameDuration;
P.valueAtTime(time-D);" in order to make the followers also respond to scale?
Love the tutorial. Extremely helpful and well explained.
Glad you enjoy it. The main difference, apart from applying the expression to the scale property, is that is needs to reference the transform.scale of another layer and not the transform.position of the other layer.
Thanks for the tutorial mate. What if the trailing obejct inpoint needs to be indepent
In what sense should it be independent?
Hey Evan, for something like a money counter graphic, i was wondering if it was possible to work that into a mogrt / expression? like have a counter that counts up/down to a number controlled by a slider within a timeframe controlled by another slider? I kinda can see how time remapping with ValueAtTime might accomplish this but was wondering if there was a better way you knew of.
It really depends on the methods and mechanism you're planning to use. Value at time could be part of it. I'm not sure it's the primary driver in such a system though. Any time we're talking about going from one value to another over a period of time, I would recommend thinking about the linear() and ease() functions that remap values like time from one thing to another.
@@ECAbrams thanks! I got something with linear that works
Hi! Great video! May I know how you made the balls move in that infinity-symbol path? Can you share with me the codes you used for this if any codes were involved? Thank you!
Hi. That infinity sign is made with one circle making the journey around using position keyframes. And others following it using the valueAtTime() that we discuss in this video. I don't think there was much more to it than than. I hope that helps.
@@evanabrams2735 Thank you so much for your answer!
Hi, I'm trying to implement the 9:40 version from scratch, It's not working and I'm not sure if the tutorial is "too old" and something has been updated to after effects, but it's not following the path of the null. (not updating it's position at least, the thing with the slider seems to work)
Is there a way to copy the value of keyframes for position? That a box follows the exact movement of another object, but at the current position of that object? (Every time I copy the position value, the objects moves to the exakt same position, which I did not want - only the value)
I also would like to know, because I want to do this with cars in traffic jam animate, please.
P=thisComp.layer(index+1).transform.position;
D=thisComp.layer("Adjustment Layer 8").effect("Slider Control")("Slider")*thisComp.frameDuration;
P.valueAtTime(time-D)
Hi Evan! I was wondering how you made the trail in the intro and outro animation go in front of and behind the text layer. I would try to tackle that problem by making them 3D layers and shifting the position ffom 1px to -1px. Is there an easier way to do this?
@@arturmartirosyan6286 But what if the trail is longer than it is now?
@@thomasnooren1714 Hey Thomas. What i did was just make everything 3d. The text, the dots. The leader dot is moving in front and then behind the text by a significant amount. Maybe 100px. I wanted a bit of size change as it went around the course. Does that make sense?
@@ECAbrams It does! Thanks!
I hope you can see this message..
Question..
what if i not only wanted to delay but also have the trails to freeze on whereever it stopped and not keep going to the leader's keyframe, (so it stays behind the leader and not overlap)
I'm not sure I understand the intention. But maybe this will help: valueAtTime() literally returns the value at whatever time you put inside the argument (). So if you did valueAtTime(time) that would be whatever the value is now. If you did valueAtTime(1) that will be whatever the value is, or was, or will be at the 1 second mark of the timeline. So, if you want to change what time is being referenced you might use a slider control inside the valueAtTime() argument or you might use x+time*y so you can control the offset and ratio of time being offset? Does that get you started at least?
Question here: I have multiple layers (like a dropdown menu) and I want to animate the top layer and the other layers follow that top layer but with a delay but also keeping the relative position at the beginning and at the end of the animation, so How can I achieve that?
thanks and sorry for my bad english
I worked with something similar and I've resolved this, dude. Share me your mail to send you my file with this expression =D
@@SrJinx mjpalacio91@gmail.com, thanks man!
@@SrJinx hey, I now it's been 2 years but can you please send me that?
hi Abrams im not sure if you would reply to a comment from a video more than a year ago.. but I have a question.
I followed through your tutorial til (8:10) and made a 'leader' and a 'follower'. it worked until here.
Then I made the 'followers' into a triangle as well and applied 'Auto-orient' to keep track of its direction.
However the first and last few frames of 'followers' had some problems. (looking at the wrong direction, layer teleports here and there..)
I don't know how the 'Auto-orient' effects the layer without modifying the rotation of a layer,
so I can only guess that I can't use 'Auto-orient' with the expression for the 'followers'.
Can you please help me understand which property is effected by 'Auto-orient' and why it can't be used with 'valueAtTime()'?
The issue with the tangents can be solved by pulling out tangents for the motion path to remove the ambiguity. That should help smooth the issues I think.
@@ECAbrams you're right. I just have to get rid of auto orient in this case. I figured that it's a zero length vector and being static should result abnormally while it doesn't move. thanks.
How do you adjust the space in between the circle? Thank you in advance!
In which sense? If you increase the difference in time between each layer that will cause a larger change in the position. But if you just want to change where the circles are you must adjust their position values. Does that make sense?
I am trying to use this technique with path points. I have created nulls from the path, so that the path points follow the nulls. I want all of the nulls to follow 1 null, but be a little bit behind, so that my shape becomes a bit wobbly. I am stuck, trying to implement valueAtTime to give my nulls a slight delay.
So my question is: How do you make an object follow another object with a delay, while still maintaining the positional difference, so that my shape stays intact?
So i figured out a solution. I had to make another null for each path-point, which was pick-whipped to the x-position of the point it had to follow. I then subtracted/added to the [temp, temp] that the pick-whip created for me, so that the null was offset by the right amount to keep my shape intact. The null, which my path-point followed, could then be pick-whipped to the extra null, so that I could add the valueAtTime-expression to that null.
If this made any sense at all, it could make for a great tutorial on how to offset without following the exact position of another object.
Great tutorials btw. I love your videos!
Hi dude, I am trying to achieve the same effect,
could you please elaborate more on the solution or it will be great if u make a tutorial on this
I simply cand create 'var' , whenever i wrote var in front of any of my variables it acuses an error "undefined value used in expression"
I think I would have to see a copy/paste of the lines you've written to really understand what's happening.
This tutorial was great!
I'm hoping somebody can help me. I'm trying to replicate a spirograph that follows a path and grows, so I need the followers to stay put instead of resolving into the leaders position.
So I have two questions:
1) Is there a way to make the following layers stay in the position instead of resolving in the leaders position?
2) Is there a way to duplicate the followers with an expression instead of duplicating the layers? I need like 500 following layers and it gets a bit crazy.
Any info on this would really help...thanks in advance!!!
1. certainly, with expressions and parenting you could cause all kind of movement having children layers ignore or adopt or modify their relative properties based on the parent's properties. thisLayer.parent.transform.rotation*-1, for example, would have a child counter-rotate as the parent rotates causing the appearance of no rotation at all in the child layer.
2. when you're dealing with 500+ elements it's best to consider a particle solution. perhaps a repeater on shape layers. Perhaps an effect or script is needed. But when you need large arrays of things to behave procedurally you'll want to look into 3rd party plugins I think.
@@ECAbrams Thank you! I'm a newbie with expressions...what would I change from your expression to make the follower stay put in it's position instead of a delay?
@@hungvinh7879 So, not follow at all? I'm not sure I follow what you're looking to see happen specifically.
@@ECAbrams Sorry I know this could sound confusing. So I want it to follow but then not resolve at the endpoint of the leader. So once the follower follows it stays in that position instead of ultimately resolving in the leaders position. Essentially leaving a trail of followers that stays put. Does that make sense? Not sure if that's even possible.
@@hungvinh7879 well, with valueAtTime(x) you'll get the value that was at time x. A static time. If you were to take the ValueAtTime(time+x) it's the current time, plus a static value. So the first example would never change or move at all because it's only referencing what the value is at that specific time. Does that help?
how to stop and start time at desired time frame ?
I'm not totally sure I understand. What are you trying to do specifically?
I 'm only here for the PunsAtTime(0:14;0:29)
i need to get "current time frame number" at "value of slider control". can you help me . how i can achieve this.
Basically i am making growing leaves on a path which has trim path on it(linked to a slider control) and all leaves are linked to path(leaves animation in a precomp). Now i want to trigger leaves animation start when trim path cross the each leaves. currently i have done it from time delay slider rig and match the speed.
this is the video link of that animation instagram.com/p/CT7E7fYJniV/?
isn't there some way to just write a script that will "add X followers" ?
So you have one layer and you would like to hit a button and have X things that are followers of that layer? I'm sure you could script up something for that. It doesn't sound impossible to me at all.
@@ECAbrams thanks I will be looking into these expressions
var P=thisComp.layer(index-1).transform.position;
var D=thisComp.layer("Adjustment layer 1").effect("Slider Control")("Slider")*thisComp.frameDuration;
P.valueAtTime(time-D)
I wanted to add .position change to my ValueAtTime and I am pulling my hair out!!! I know it's gotta be easy.
are you trying to find the value of a position property at a certain time? Or what's the combination of position with value you're looking to achieve?
@@ECAbrams basically looking to do this:
thisComp.layer(index-1).transform.xPosition+140;
valueAtTime(time-.5)
Try to move stars in at different positions with delay. I know I am missing something easy but I am new to expressions. Thanks for the reply.
came for the tutorial, stayed for the jokes...
So cool learning AE from Seth Rogan 😁
I suppose all Canadians of a certain age do sound the same eventually.
Nice pun ! lol
Finally someone appreciates the true value of the channel!
Abrams at his brutalist
Oh, I am always brutal... but more like the architectural style.
Punny that...
This is not a good tutorial, unnecessarily complicated and dives right into examples without first explaining what the expression actually does....
P=thisComp.layer(index-1).transform.position;
D=thisComp.layer("Adjustment Layer 1").effect("Slider Control")("Slider")*thisComp.frameDuration;
P.valueAtTime(time-D)