The need for a launcher.

(Apologies in advance for this not being a tutorial. Here’s a link to download my launcher to dissect.) If you’ve dabbled in After Effects scripting, you know how messy your File > Scripts… and Window menus can get with all those .jsx listings. Those one-off scripts you write and load into AE really stack up. Let me make a case for a launcher you write for yourself.

Panels you can download or buy– like rd_ScriptLauncher or KBar— have their place for easy maintenance within AE and end-user-friendliness. If you’ve bought/downloaded/organized an arsenal of scripts, it makes a lot of sense to load them dynamically from jsx files. For scripts you write yourself, though, a launcher whose backend you maintain will make you more thoughtful about your own work.

Screen real estate is my first consideration when writing a dockable panel. A launcher with a drop-down list and a couple of buttons fits perfectly at the bottom of your Project panel, yet can pack in the functionality of tens of scripts (navigating a drop-down has its limitations).

A list of scripts that no longer need to clutter File > Scripts… is a step in the direction of making After Effects your own.

As I mentioned above, the launcher I maintain for myself has three elements:

  1. A drop-down list – populated and maintained with all of the scripts.
  2. An ‘execute’ button – a basic button element that runs the current drop-down-selected script.
  3. A ‘help’ button – A button that kicks out an alert with a description and any special instructions for the current drop-down selection. (More on this later.)

The drop-down list

I’ll admit: the way I currently maintain my launcher is basic and unnecessarily manual. It leaves a lot of room for things to go overlooked and disconnected. I simply hard-code text into the drop-down list array for every script (in my case, a resource string):

DropDownList{properties:{items:['calculatedNull', 'circlePath', 'connector', 'convexHull', 'destroyFolderStructure','expressionSwitch','everyOtherLayer','face', 'fastShape', 'isolateProperties','lookAt', 'nullInPlace','parentChain','quickBake', 'replaceWithSolid','restoreOrder','selectImmediateChildren','selectUnparented','strayFileFinder','toComp','unevenWheel', 'versionUp']}, preferredSize:[200,25]},\

From there, I use switch statements (within both the execute and help button onClick functions); they look at the string value of the current drop-down selection.

The execute button

The beauty of a launcher with a button is the ability to add keystroke modification. You can build lots of customization into your script when you have keystrokes at your disposal. For example, a script could operate on just the selected layers by default; all layers with shift held down; or the just deselected layers with alt/opt held down.

var shiftPressed = ScriptUI.environment.keyboardState.shiftKey ? 1 : 0;
var altPressed = ScriptUI.environment.keyboardState.altKey ? 2 : 0;
sm_fastShape(shiftPressed + altPressed);

Think about your arsenal of scripts and what they do. Do you have scripts in File > Scripts… that are simply forks of another script that accomplish basically the same thing? Are there small tweaks you can make to the original that would accomplish the same functionality if you had that key-press?

The onClick function for my execute button is always a simple function call to the script itself (with key-press logic mentioned above, if needed). Working this way (wrapping each individual script into a function) allows me to break out the scripts quickly and easily to their own .jsx, if necessary. (I’ll generally just force a no-key-press into the function arguments if I make the script standalone. Though, as I’ve written more and more scripts, I’ve internalized/standardized key-press logic in my brain, so I can fake/hardcode a key-press quite easily if I need to.)

The help button

A handful of the scripts written into my launcher are expression-helper scripts– scripts that allow me to quickly and dynamically generate an expression with layer links based on the layer selection at the time of running the script. I can do this by strategically selecting the layers and properties in a certain order. The help button is a way to remind me what that correct order is.

An example. I have to preface this example with the fact that I wrote this script before Adobe added expression-driven shape paths. One of the only ways to make dynamic/procedural polygons (without third-party plugins) was using CC Power Pin or Corner Pin with expressions in the corner properties. Creating complicated shapes (like ribbons or triangle-faceted faces) meant doing that linking over and over across many solid layers and a lot of ‘corner layers’.

Consider a script that takes a selection of 4 null objects and ‘plate’ layer that will eventually get tracked to a surface with a corner pin. Sure… you could create a CC Power Pin on the plate, manually input the expressions on each corner, pick-whip the layers for each expression… etc. etc.

A simple script is the perfect solution to save that time. The only thing you really have to think about is the way the script will know how to fill the expression for the Top Left corner vs. the Bottom Right corner (vs. the other two… and then which layer gets the CC Power Pin effect).

{
  var comp = app.project.activeItem;
  var l = comp.selectedLayers;

  if (l.length !== 5){
    alert("Select 5 layers in this order:\n" +
      "1. Top left corner.\n" +
      "2. Top right corner.\n" +
      "3. Bottom left corner.\n" +
      "4. Bottom right corner\n" +
      "5. The layer to apply the corner pin."
      );
  } else {
    app.beginUndoGroup("sm_face");
    var cp = l[4].Effects.addProperty("CC Power Pin");
    cp(1).expression = "tl=thisComp.layer(\"" + l[0].name + "\");\n" +
          "fromComp(tl.toComp(tl.anchorPoint));";
    cp(2).expression = "tr=thisComp.layer(\"" + l[1].name + "\");\n" +
          "fromComp(tr.toComp(tr.anchorPoint));";
    cp(3).expression = "bl=thisComp.layer(\"" + l[2].name + "\");\n" +
          "fromComp(bl.toComp(bl.anchorPoint));";
    cp(4).expression = "br=thisComp.layer(\"" + l[3].name + "\");\n" +
          "fromComp(br.toComp(br.anchorPoint));";
    app.endUndoGroup();
  }
}

This script is a standalone version. You can save that to a .jsx and run it by itself. You can see that I included a basic error-check; it alerts you to the fact that you don’t have the correct number of layers selected. When I added this script to my launcher, though, I just copy/pasted that alert into the onClick for my help button, so I could quickly remind myself the order without intentionally running the script incorrectly for the sake of the alert.

Wrapping up.

The advantage of a low-profile, well-maintained launcher is having a script (whichever script you need in the moment) at the ready– docked to your interface, one button-click away. Sure: the built-in Run Last Script keyboard shortcut is cool (Command/Control+Opt/Alt+Shift+D), but it can’t handle a key-press.

Lastly, your launcher will allow you to sneak a script into the interface without restarting AE. Close the panel window, save the updated launcher in your text editor, and reopen the window. One disadvantage is that you don’t get all of the built-in debugging/error alerts if the script you’ve added isn’t up to snuff, so…. get better at scripting.

Published by thatsmadden

I'm an animation artist with an interest in code-driven motion.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: