Learn how to integrate TexturePacker with Xcode’s Build Rules:
- benefit from Xcode’s ability to compile several files
- use .tps files as an integral part of the build process
- add build rules for each different texture formats
David Hart is an iOS developer that has released an iPhone puzzle game named GraviMaze on the App Store using Cocos2D and TexturePacker. He’s found a way of integrating TexturePacker with Xcode using Build Rules and would like to tell us about it.
A Small Problem
The standard method for integrating TexturePacker with Xcode is a life saver if you are used to compiling your sprite sheets manually, but it has a few issues. First of all, it does not benefit from Xcode’s ability to compile several files in parallel. It also forces you to include in Xcode the output sprite sheet and data files which should not be under source control - not the cleanest solution.
An Alternative Solution
One solution I’ve come up with is to have the project only include the .tps files and to teach Xcode how to compile them into the sprite sheet and data files using Build Rules. The TexturePacker files will now be an integral part of the build process instead of relying on a post-build script. Out of the box, Xcode will not recompile sprite sheets if there are no changes, and will delete them during the Clean process.
When compiling sprite sheets, the build process will run one TexturePacker compilation per CPU core. It speeds things up, but can bring your computer to a crawl.
/usr/bin/nice. This reduces the thread priority of TexturePacker.
Secondly, Xcode will need to rebuild sprite sheets for each platform/configuration combination. Finally, because of how Build Rules are defined, you will have to setup separate rules for each different texture format.
Now that you are aware of all the pros and cons, if you still want to setup Texture Packer with build rules, here is how to do it:
- If you were using the previous integration technique you must:
- Remove all references to the sprite sheets and data files in Xcode.
- Remove the Run Script phase from your target’s Build Phases.
- Rename tps files with a different postfix depending on the texture format it outputs.
For example, I have renamed those that output high quality png files to -High.tps and those that output lower quality .pvr.ccz files to -Low.tps.
- Add references to the .tps files in Xcode.
XCode's Project Navigator Before and After
- Finally, you need to add one build rule for each different texture format like so:
- Process: Source files with names matching: *-High.tps (the regex you chose earlier)
- Using: Custom script:
// Define here your data and sheet file names data="$PROJECT_DERIVED_FILE_DIR/$INPUT_FILE_BASE-hd.plist" sheet="$PROJECT_DERIVED_FILE_DIR/$INPUT_FILE_BASE-hd.pvr.ccz" /usr/local/bin/TexturePacker --data "$data" --sheet "$sheet" "$INPUT_FILE_PATH" // This is necessary to force Xcode to run TexturePacker every time and let it // decide if the sheets needs to be recompiled touch "$INPUT_FILE_PATH"
Behind the scenes
Build rules, as their name implies, allows us to inject custom scripts into the build process to handle certain files. By specifying the input file pattern, and what output files to expect, Xcode can intelligently chain multiple build rules together and copy the resulting files into the final bundle. Once you understand how it works, this can be applied to replace other build phases. For example, I now use the following build rule to generate iPhone compatible caf files from my sound designer wav files:
output="$PROJECT_DERIVED_FILE_DIR/$INPUT_FILE_BASE.caf" /usr/bin/afconvert -v -f caff -d LEI16 -c 1 "$INPUT_FILE_PATH" "$output"
If you wish to learn more concerning build rules, have a look at these other blog posts: