There's a tipping point that I think happens with any commercial artist where the repetitive and mundane tasks of churning out work seriously begin to eat into productivity. When that starts to happen, smart artists start to look for scripts, plugins, or templates that allow them to off load those tasks. With sites like Gumroad and Aescripts, its hard to hit a wall that some one hasn't already written a tool to get around.
But what happens when you do find that wall? Or what happens when your task is so specific to YOUR workflow that someone else's solution is only a half measure? You either lean into the suckiness of whatever task you are doomed to repeat into infinity, or you put your foot down and say enough is enough, and you make your own solution. And this is the place we found ourselves on several occasions this year.
Without getting too much into specifics, one of the most demanding things we worked on last year was a technical animation for an engineering firm. In generic terms, the robot that we were tasked to animate is meant to travel through a pipe while a component near the aft of the unit rotates and maintains contact with the inside of the pipe wall. In our initial meetings with the client we completely missed this as a very critical technical challenge. The client was super specific that the rotating component must, at all times, stay in contact with the pipe wall through 90º bends in any direction. In the moment we said no problem and figured it would be easily animated. It sounds simple enough! But in reality, as we started testing our rig, it became a massive problem. Here's an exaggerated example of what was happening:
If you watch the green arm as the bot enters the curve, you can see that as it points toward the inside of the curve it falls away from the wall and as it swings to the outside it pokes through. My first instinct was to just fix it by hand. I went through and keyed the arm extending and retracting as necessary, and at first it was fine. But then we got word that the rotating component was spinning too slow. WAY too slow. Once it was rotating at the correct speed it became almost impossible to hand animate the extension and retraction. Even if it HAD been possible, any further change in animation meant reanimating the entire section. So I made the decision to find a way to automate it.
What I needed was a way to measure the distance from the center of the pipe to the pipe wall in a very specific direction, and I needed to be able to easily control and animate the start point of the measurement AND the direction it measured. That was about the time I realized there was nothing inside Maya that could exactly what I needed to do.
The closestPointOnMesh node requires a point in space first, then it looks for the nearest point on a collider mesh. Sounds close enough...but with some testing I found that the closest point (in any direction) to the end of the swinging arm isn't always in the direction it's pointing. Check out the image and you can see that the closestPointOnMesh node does provide the closest point but I needed the closest point along a specific vector. I needed a ray caster, and my only option at this point was to dig into the API and make something that did just that.
Thankfully, after a good but of digging and research I found an old raycasting script by Jason Osipa on Highend3d. This script got me 80% of what I wanted. It took a source point and measured to a mesh in a direction. But it required the direction to be provided as a vector, and I could never quite get that working in a way that was easy to animate. So I took it apart and reworked it so that I could provide it a collider mesh, a start location, and an end location. The node would calculate the vector between the two without the user having to figure it out or create extra nodes in between. The result point could be connected to a distanceBetween node and used in whatever way I needed.
The difference is subtle in this final version...but was really important to the client. In the end...the script was sloppy but functioned well enough to save me a HUGE headache when the changes started rolling in.
One of the other things I found myself doing OVER and OVER and OVER this year was naming character art layers in After Effects and Harmony. Our workflow for hybrid cut out character animation in those programs has typically started with characters being designed and created in Illustrator. Transitioning those designs to After Effects hasn't been too much of a headache, and since Overlord came out it's even gotten more streamlined. Harmony, on the other hand, doesn't include a simple way to import Illustrator files. You can bring them in...but their layer order and names are stripped. I am a stickler for naming and organization...and this is my worst nightmare.
Even with best intentions, proper naming doesn't always happen in the heat of rush job. Sometimes we forget, sometimes we mislabel things, and sometimes we decide in rigging that something we build as one piece to be animated with deformers should be cut into multiple pieces and puppetted more directly.
This problem came to a head on a recent animation for Farah & Farah, where I found myself in an After Effects composition with 277 layers, and a huge chunk of them needed to be renamed.
I've always used a naming convention that was something like characterName_sideOftheBody_partName. So what I wanted was an interface that let me fill out a character name, set some default abbreviations for left and right, and naming seperator. The interface would have a series of predefined buttons for body parts and face parts. Selecting a layer and clicking a button would rename the selected layer using my convention. The goal was to reduce the number of interactions required to get a layer named, and it seems to have accomplished that goal by good bit.
Still have some things to fix on this: Plently of little bugs and error catchers to work out, and would eventually like to implement a way to customize the convention itself, etc. But for my purposes it's working well!
With After Effects handled, Harmony became the next order of business. Scripting in Harmony uses a different language (of course), but since it uses QT it was super simple to create the UI with QT Designer. I was able to convert the ExtendScript over and had it up and running pretty quickly.
Deciding to solve problems through scripting is definitely a weird jump to make. There is a cost / benefit tipping point when it comes to the amount of time you're going to invest creating your first script or plugin or what ever. Especially if your primary role is a creative one and code is scary. The first thing you create will most likely take a good bit longer than if you had just done what ever you were out to accomplish manually. But like most things...the more you do... the faster you'll be.
Things I've learned along the way:
- There is a huge difference between writing a tool or script to get you through a project and writing one that you'd be willing to distribute to a team. If you're the only person using it, it doesn't have to be perfect.
- Find a good starting place. Most likely someone has already come pretty close to creating what you need, so pick up where they left off and push it the rest of the way.
- There are tools to help build tools! In After Effects scripts like rd_GimmePropPath helps when you can't remember the ridiculously complex After Effects Object Model. I also used p9UI to help plan the UI for DBNameIt.
- Get a good script editor. I've been using Atom for a while and absolutely love it. It's fully customizable, interfaces with Git (if you want it to), and has packages that allow proper color coding and indentation for MEL and ExtendScript. There is even a package that lets you run shell commands directly from Atom.
There are an absolutely ton of references out there for most of this stuff. Here are a few:
- David Torno's ExtendScript training series is free and is an awesome place to start.
- FxPhd has several outstanding courses from Lloyd Alvarez and Mathias Möhl. Lloyd's course is older and a little out of date, but is still a fantastic primer. Mathias's courses (there are 3) are more up to date, and go pretty freaking deep. The Advanced Scripting courses were where I learned how to integrate Atom into ExtendScript development a lot more seamlessly.
- Redefinery - More awesome info on AE scripting
- On the Maya development side, I spend a ton of time on Chris Evans blog. There were so many helpful nuggets in there.
- Practical Maya Programming with Python by Robert Galanakis