Mike Foran
Forum Replies Created
-
Exactly! I knew there had to be a simpler method than what I was doing. Thank you.
-
Bingo! That’s the ticket. Thanks Walter.
-
could you parent the light to a null and use stardusts starting keyframe to parent to the position of the null?
Yes, but the issue here is that I am trying to adjust the path of the light that the particles are to follow (actually several of them) and if I move the first keyframe of the light position, the entire path of particles becomes offset from the path. The emitter position of Stardust needs to have the same coordinates as the first keyframe of the light path. So parenting the light to a null doesn’t solve my issue in this case. Thank you though.
-
I think that will do for now but I was hoping for something that would identify the first keyframe and pull that value. From other posts it does involve valueAtTime and key(1) but I can’t seem to figure the correct syntax. This is what I have so far, which does not work:
L = thisComp.layer("Motion Path A")
if (L.transform.position.numKeys > 1){
v1 = L.transform.position.valueAtTime(key(1));
}else{
L.transform.position
}
This gives me an error that “this property has no keyframe number 1” although it does. I think I’m just not addressing the layer properly?
-
I’m pretty advanced actually. I’m looking for a dynamic solution. Not sure if explaining the issue helps, but I’m trying to use a light path to control the path of particles in Stardust. When you use a Motion node in Stardust to do this, it bases the emitter on the location of where the light’s motion path starts. So if I move the starting position of the light, the the entire path of the particles shifts. I have to keep copying the starting point position of the light to the position of the emitter so the particles align to my light’s path.
This is a pain in the butt. I thought if I could just have an expression that would automatically retrieve the position of the light’s first keyframe for the position of the emitter, it might make this a lot easier to work with. I thought I understood it but I can’t seem to write an expression that isn’t broken.
-
Sorry I just re-read my original post and the script I provided didn’t completely solve it. Here’s a more detailed script that references two sliders named ‘On and ‘Off’ that are on a controller null.
on = thisComp.layer("Controller").effect("On")("Slider");
off = thisComp.layer("Controller").effect("Off")("Slider");
range = on+off
it = Math.floor(time / range)
if (time > range) {v = time - ( it * range)} else {v = time};
if (v > on) {e = 0} else {e=500};e
This script sets the emitter to 500 for however many seconds the ‘On’ slider indicates, and sets it to 0 for however many seconds the ‘Off’ slider indicates. But like I said, accuracy is based on your frame rate and the speed of the emitter, which created overlapping patterns in the emitter. It wasn’t working for this usage. I’m sure there’s a more elegant way to write it.
-
I messed around with keyframing first, but it was cumbersome. The emitter path is a really long path and I wanted an easy way to control the line with a couple sliders that determine the rate at which the emitter would turn on and off. I actually solved it myself, although the results weren’t what I wanted. Despite the path being long the emitter wasn’t traveling slow enough to give acceptable results, and the line suffered from interference patterns between the frames and the emitter rate. Subframe sampling doesn’t work in Particular for an emitter expression, only path shapes. This created uneven dotting.
I’m not terribly competent with expressions so I am sure someone could create a more elegant bit of script, but this is the essence of what I ended up with:
range = 8
it = Math.floor(time / range)
if (time > range) {v = time - ( it * range)} else {v = time};v
This doesn’t include the additional sliders for specific on/off controls. But it uses time to increase a variable that loops from 1 to 8.
-
I presume the “hasVideo” and “active” return a 1 if True, and Opacity anything over 0 would be visible, so if all three of those attributes are 0 then it sets the string to the name of the layer. Otherwise it remains blank, as set in the opening line, and checks the next layer.
-
Excellent Dan, thanks. If I might ask, what does the exclamation point in the IF statement do?
-
That is better but it was not getting the data for an edit until 1 frame after the in-point. I added the “=” back in to the in point check, so it’s like this:
a = thisLayer.index;
b = thisComp.numLayers;
for(i = a+1; i <= b; i++){
curLay = thisComp.layer(i);
if(curLay.inPoint <= time && curLay.outPoint > time){
curLay.name;
break;
}else{
“”
}
}Thanks again for taking the time on this. It will be very helpful for a number of projects.