ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Script to duplicate and offset layers

COW Forums : Adobe After Effects

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Jake BartlettScript to duplicate and offset layers
by on Jul 14, 2011 at 11:27:33 pm

This is my first post on creative cow. I've used it as a resource for years now whenever I need help with something in after effects. Now I finally have a question that I think is a little too specific for searching the forums for.

I do not know scripting for after effects -- at all. I thought it would be nice to know how to create some basic scripts to automate a few tedious actions I have to do on a daily basis. The first thing I would like to try to write a script for is to duplicate a layer multiple times at once.

To be more specific, I want to automate faking 3D text by duplicating and offsetting the anchor point of a layer of text a number of times.

Like I said before, I don't know the first thing about scripting. Having the ability to control the number of times the layer is duplicated and offset would be nice, but not necessary. If I could have a set of 3 different scripts that duplicated and offset the layer 3 different amounts, that would be just as helpful. Also automating the next step I always take, parenting all of the duplicate layers to the original, would also be nice. Again, not a deal breaker if it's too complicated.

I did some sniffing around in the After Effects CS3 scripting guide, and came across this line of code:
app.project.item(index).layer(index).duplicate( )
But that's about as far as I got. I attempted to run that line of code as a script in AE but got an error saying I hadn't defined "index". I realize I'm probably missing plenty of common sense when it comes to scripts; I'm just completely in the dark as I've never messed with it before.

So my first question is, how likely is it that the task I'd like to automate is something simple enough for me to attempt to learn how to start scripting on? And if it is a good place to start, is anyone willing to help me write it up?

Thanks very much,
Jake


Return to posts index

Brian CharlesRe: Script to duplicate and offset layers
by on Jul 15, 2011 at 12:56:19 am

I wrote something similar earlier this year and added controls to a null for offset in x y and z.

You're welcome to use what you like:


// offset layers beta
// ©February - March 2011 Brian Charles version b.05
// Apply to layer below to Copy and Offset Position and Rotation.
//Adds a null with sliders to adjust offset and rotation in X, Y and Z.
// Scale linked to top layer.
//Opacity Slider added Mar 2/2011
// Check for Selected Layer March 5/2011
// added function March 5/2011
// you must have a layer selected to make this work.
// Brian Charles

var myComp = app.project.activeItem;
var undoStr = "Layer Offset";
if (myComp == null || !(myComp instanceof CompItem)) {
alert("A Comp must be active to run this script");
} else {
app.beginUndoGroup(undoStr);
var myLayer = myComp.selectedLayers;

if (myLayer == null) {
alert ("Select a Layer");
}else{

var thisLayer = myComp.selectedLayers[0];

if(thisLayer){
offset3D();
}else{
alert("Select a layer first.")
app.endUndoGroup();
}
}
}
function offset3D() {
var theNum = prompt("How many copies:", "1");
thisLayer.threeDLayer = true;
thisLayer.duplicate();
// make a null object
var controlNull = myComp.layers.addNull();
controlNull.source.name = "3D Offset Control";
//add a sliders for X Y and Z Position
var offset = controlNull("Effects").addProperty("Slider Control");
offset.name = 'Layer Offset (X)';
var offset = controlNull("Effects").addProperty("Slider Control");
offset.name = 'Layer Offset (Y)';
var offset = controlNull("Effects").addProperty("Slider Control");
// add angle controls for X Y and Z Rotation
offset.name = 'Layer Offset (Z)';
var offset = controlNull("Effects").addProperty("Angle Control");
offset.name = 'X Rotation';
var offset = controlNull("Effects").addProperty("Angle Control");
offset.name = 'Y Rotation';
var offset = controlNull("Effects").addProperty("Angle Control");
offset.name = 'Z Rotation';
var offset = controlNull("Effects").addProperty("Slider Control");
offset.name = "Opacity Offset";
// duplicate the layers and
// add the script to the selected layer
for (i = 0; i < (theNum-1); i++) {
var posExpression = 'x =thisComp.layer(index-1).transform.position[0]+thisComp.layer("3D Offset Control").effect("Layer Offset (X)")("Slider"); y=thisComp.layer(index-1).transform.position[1]+ thisComp.layer("3D Offset Control").effect("Layer Offset (Y)")("Slider");z =thisComp.layer(index-1).transform.position[2]+ thisComp.layer("3D Offset Control").effect("Layer Offset (Z)")("Slider");[x,y,z]';
thisLayer.position.expression = posExpression;
var xRotExpression = 'thisComp.layer(index-1).transform.xRotation+thisComp.layer("3D Offset Control").effect("X Rotation")("Angle")';
thisLayer.xRotation.expression = xRotExpression;
var yRotExpression = 'thisComp.layer(index-1).transform.yRotation+thisComp.layer("3D Offset Control").effect("Y Rotation")("Angle")';
thisLayer.yRotation.expression = yRotExpression
var zRotExpression = 'thisComp.layer(index-1).transform.zRotation+thisComp.layer("3D Offset Control").effect("Z Rotation")("Angle")';
thisLayer.zRotation.expression = zRotExpression
var scaleExpression= 'thisComp.layer(index-1).transform.scale';
thisLayer.scale.expression = scaleExpression;
var opacityExpression = 'D = thisComp.layer("3D Offset Control").effect("Opacity Offset")("Slider");thisComp.layer(index-1).transform.opacity - ((D/10)*-1)';
thisLayer.opacity.expression = opacityExpression;
thisLayer.duplicate();
}
}



Return to posts index


Brian CharlesRe: Script to duplicate and offset layers
by on Jul 15, 2011 at 1:56:53 am

Here is an updated .jsx file. I haven't written this as a Script UI panel, you can put it in the Scripts folder and run it from there.

2599_3doffsetbeta.jsx.zip



Return to posts index


Jake BartlettRe: Script to duplicate and offset layers
by on Jul 15, 2011 at 7:21:27 pm

Brian,

Thanks so much! Your script is very close to what I was trying to automate. I managed to chop it down to the only property I need to be able to offset; the z-axis anchor point.

// Create the palette-type window (a modeless dialog)
var win = new Window('palette', '3D Layer Offset');
this.windowRef = win;
// Create a container panel for the components
win.pnl = win.add("panel", [5,5,170,80], 'Offset Controls');
// Use the panel's add() method to create components
win.pnl.stxt=win.pnl.add('statictext',[10,15,100,35],"Duplicate #:");
var theNum = win.pnl.add('edittext', [90,15,140,35], '10');
// Add OK/Cancel buttons
win.pnl.okBtn = win.pnl.add("button", [10,40,60,60], 'OK');
win.pnl.cnlBtn = win.pnl.add("button", [90, 40, 140, 60], 'Cancel');
// Define the behavior of the buttons
win.pnl.okBtn.onClick = function()
{
//alert("button pressed"); //debug
offset3D();
}
win.pnl.cnlBtn.onClick = function()
{
$.writeln("Cancel Button Pressed");
win.close();
}
// Display the window
win.show();
function on_textInput_changed()
{
// Set the duplicate number based on the text.
//alert("In text change");// debug
var value = theNum.text;
if (isNaN(value)) {
alert(value + " is not a number. Please enter a number.", scriptName);
} else {
//alert("Value is "+value);//debugging
theNumVal = value;
}
}
function offset3D() {
//alert("In 3D");
var undoStr = "3D Layer Offset";
app.beginUndoGroup(undoStr);// begin UNDO group
on_textInput_changed();//check that its a number not letters
// alert(theNumVal);//debugging
var myComp = app.project.activeItem;
if (myComp == null || !(myComp instanceof CompItem)) { // A COMP MUST BE SELECTED
alert("A Comp must be active to run this script");
} else {
var myLayer = myComp.selectedLayers;
if (myLayer == null) {// check a layer is selected
alert ("Select a Layer");
}else{
var thisLayer = myComp.selectedLayers[0];
if(thisLayer){
thisLayer.threeDLayer = true;
thisLayer.duplicate();
// make a null object
var controlNull = myComp.layers.addNull();
controlNull.source.name = "Anchor Point Offset Control";
//add a sliders for Z anchorPoint
var offset = controlNull("Effects").addProperty("Slider Control");
offset.name = 'Layer Offset (Z)';
// duplicate the layers and
// add the script to the selected layer
for (i = 0; i < (theNumVal-1); i++) {
var posExpression = 'x =anchorPoint[0]; \n y=anchorPoint[1];\n z =thisComp.layer(index-1).transform.anchorPoint[2]+ thisComp.layer("Anchor Point Offset Control").effect("Layer Offset (Z)")("Slider");[x,y,z]';
thisLayer.anchorPoint.expression = posExpression;
thisLayer.duplicate();
}
}else{
alert("Select a layer first.")
app.endUndoGroup();
}
}
}
}


This is already extremely helpful because of the ability to duplicate layers after running the script, and having them automatically offset. My next question, however, is would it be possible to have the script parent all of the duplicate layers to the original? If the layers are parented, I only have to animate the parent layer. That makes my job a lot more efficient.

Again, thanks so much for your script. It's already helping me work more efficiently.


Return to posts index

Brian CharlesRe: Script to duplicate and offset layers
by on Jul 15, 2011 at 7:53:50 pm

[Jake Bartlett] "would it be possible to have the script parent all of the duplicate layers to the original?"

Yes. Here is a code snippet from a Camera Rig I scripted that should point you in the right direction.

var controlNull = myComp.layers.addNull();
controlNull.source.name = "Master Camera Control";
controlNull.threeDLayer = true;
controlNull.shy = false;
myComp.hideShyLayers = true
newCamera.parent = bankNull;
bankNull.parent = pitchNull;
pitchNull.parent = headingNull;
headingNull.parent = controlNull;

Also check out http://aenhancers.com/

These scripting tutorials may assist you as well: http://www.batchframe.com/tutorials/



Return to posts index

Jake BartlettRe: Script to duplicate and offset layers
by on Jul 26, 2011 at 6:22:13 pm

Thanks again for your pointers Brian. I got a little further with your help, but still don't have a completely functional script. I started a thread at aenhancers a couple of weeks ago but I've had no responses, so I guess I'll repost my questions here.

What I have so far is a script that will duplicate a selected 3D text layer a specified number of times, create a null with a slider control, and add an expression to each text layer linking the z-axis anchor point to the null's slider control. This allows me to control the look of an extrusion with the slider, and to add more density, all I have to do is duplicate any of the text layers as many more times as needed and they are automatically offset evenly. It's very helpful already. However, it has some issues. You can access the script here: 2689_anchorpointoffset.jsx.zip

If I want to run the script on more than one text layer, it creates a null with the same name. That messes with the expression and all of the text layers I've created with the script follow the null that was created last. This prevents me from being able to have animated extrusion or different values of extrusion per 3D text. So my first question is...

1. How do I get the script to generate a unique name for the null every time I run the script?

The next issue I've been trying to figure out is how to parent all of the duplicate text layers to the original? Actually, the way the script works now, the first duplicate layer doesn't have the expression applied, and leaves the anchor point set to 0. So that layer would probably be my first choice of which layer to parent the duplicates (and in that case, the original) to, but either would work equally. So for the sake of consistency...

2. How do I parent all of the duplicate layers to the original?

And finally, I've noticed that if I set any parameters for the text's orientation, after running the script, they are all reset back to 0.

3. Can the script leave all pre-set attributes alone?

Thanks in advance for reading this. I don't know the first thing about writing my own script, this is just something I've taken on for myself and my co-workers as it would automate this tedious task each of us have to do on a daily basis.

http://whoknew.news.yahoo.com


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 CreativeCOW.net All Rights Reserved
[TOP]