Automating my WorkFlow with TexturePacker’s Command Line Options

At work I use TexturePacker quite a bit to generate sprite sheets for UIToolkit from within Unity. Each sprite sheet ends up corresponding with a layer in UIToolkit, so the sheets we use are typically named “layer0.png”, “layer02x.png”, “layer0.txt”, “layer02x.txt”, where the .txt files are the metadata files.

During development, I’ll be interrupted every now and then with new and improved assets that need to pushed up into the Unity application. Once I have received the asset, I must take a series of steps to actually use that asset in Unity.

I open the TexturePacker .TPS file and drag the asset in. The sprites get re-arranged then I would perform the following:

  • Set the sheet filename for use with retina mobile devices, adding “2x”
  • Set the width of the sheet to 2048
  • Set the height of the sheet to 2048
  • Set scaling to 1.0
  • Click publish

I would then need to do the same thing for non-retina devices. UIToolkit will automatically select the appropriate sized sprite sheet to use based on the “2x” extension.

  • Set the data filename for use with non-retina mobile devices, removing “2X”
  • Set the width of the sheet to 1024
  • Set the height of the sheet to 1024
  • Set scaling to 0.5
  • Click publish

Once TexturePacker creates the 4 files (layer0.png, layer0.json, layer02x.png, layer02x.json ), I would rename the .json files to .txt to keep Unity happy. This process would be done over and over again, until insanity.

Automating Things

This weekend I had some time to investigate a way to automate this tedious process. I wanted a solution such that after editing the .TPS file, I could simply run a script that would take care of the rest of the work. I began by looking into TexturePacker’s command line options. After some tinkering, I came up with a short script that reduces the number of click and edits that I need to make.

I placed the script within the directory that contains all our assets. However, since the output sheets go into a folder that only contain the sheets and data files, so I need to reference these paths relative from where the shell script lives. So, this would be a script for one layer for UIToolkit:

TexturePacker --sheet ../Resources/layer0.png    --data ../Resources/layer0.txt    --scale 0.5 --width 1024 --height 1024 --format unity layer0.tps
TexturePacker --sheet ../Resources/layer02x.png  --data ../Resources/layer02x.txt  --scale 1.0 --width 2048 --height 2048 --format unity layer0.tps

Note that I can omit changing any of the options that are already set in the .TPS file such as padding, rotation, algorithm, etc. This helps keep the script short and sweet.

The options all correspond with the changes that I mentioned previously. One interesting thing to note is the –format option which prevents needing to rename the .json data file to .txt. You might ask why I didn’t just set this option in the TexturePacker GUI. The reason is, I had just learned about this option after looking over the command line help!

I had created a script that I could run through command line, but I wanted the script to be easier to use. If I had just edited the .TPS file, I would be in Finder, and being able to double-click the script would be nicer than opening a terminal to execute it. Running the script through Finder would simply return an error since the terminal would be in my home directory.

To fix this issue, I had to modify the script a bit more:

DIR="$( cd "$( dirname "$0" )" && pwd )"
TexturePacker --sheet "$DIR"/../Resources/layer0.png    --data "$DIR"/../Resources/layer0.txt    --scale 0.5 --width 1024 --height 1024 --format unity  "$DIR"/layer0.tps
TexturePacker --sheet "$DIR"/../Resources/layer02x.png  --data "$DIR"/../Resources/layer02x.txt  --scale 1.0 --width 2048 --height 2048 --format unity  "$DIR"/layer0.tps

When the shell script runs, we get the directory name where the script lives, cd into that directory and call pwd and assign that value into our DIR variable. This part took a bit more time as I learned spaces on either side of the equals sign will confuse bash, so I had to leave those out.

Now, if a new asset is sent to me, I open the .TPS file, add the file and save. Then I can run this script by a simple double-click. Tada!

Next steps

Using this method, I need to create a shell script for every UIToolkit layer. This isn’t nearly as bad as it sounds since we typically only have 2-3 layers. But, what I’d like to do in the future is investigate AppleScript. AppleScript can help convert a shell script into an app that allows files to be dropped on that app. If I did this, I could drop the .TPS file onto app, then the the script could extract the filename and do the rest. This would prevent needing a script for every layer.