Packaging Assets for Unity

Unity is a great platform for developers. At TestFairy, we’re committed to helping Unity developers that want to use our SDK. Part of that commitment means providing developers with little or no impedance when it comes to installing our SDK. In this post, we’ll talk about how we package our app as a .unitypackage to improve the installation experience.

Until recently, we deployed the TestFairy Unity SDK as a zip file with our Android and iOS libraries. This approach works, and we will continue to maintain releasing our SDK in this package for many of our clients. However, for other clients that prefer more unity (pun intended) between other native plugins, we decided to also package our library as a .unitypackage.

The first thing we needed to get a handle on is what exactly is a .unitypackage? If you run file on any .unitypackage, you’ll see that its just a gzip file. Running tar -ztf on any .unitypackage, and you’ll get something that looks as follows:

0906f4c19cd164ff99261f4ca645a9b9/asset.meta
0906f4c19cd164ff99261f4ca645a9b9/pathname
ca9aea00281ee42e6b0168c2b7d7613b/asset.meta
ca9aea00281ee42e6b0168c2b7d7613b/pathname
ca9aea00281ee42e6b0168c2b7d7613b/asset
...

Whoa!! What’s all this??

Unzipping the package, and looking at each file, you’ll see that it all seems to have a purpose. Starting with the directory name itself, you can see that directories seems to have an asset.meta and pathname file. And it appears that some directories have an asset file.

Picking any directory, and running file on the pathname file first, you’ll see notice its just a plain text file. Looking inside the file, you should see something like this:

Assets/Plugins/Android/testafairy-android-sdk.aar

Ah, ok, so the pathname seems to just be the destination directory! It also seems to answer the question of what the asset is. In this case, its the actual file (and in our example above is the Android .aar).

Ok, so of the two files in any given directory makes sense. What about that last asset.meta? Running file on that file, you’ll see that it’s also just a plain text file. Dumping the contents of asset.meta, you should see something as follows:

fileFormatVersion: 2
guid: ca9aea00281ee42e6b0168c2b7d7613b
PluginImporter:
  externalObjects: {}
  serializedVersion: 2
  iconMap: {}
  executionOrder: {}
  defineConstraints: []
  isPreloaded: 0
  isOverridable: 0
  isExplicitlyReferenced: 0
  validateReferences: 1
  platformData:
  - first:
      Android: Android
    second:
      enabled: 1
      settings: {}
  - first:
      Any:
    second:
      enabled: 0
      settings: {}
  - first:
      Editor: Editor
    second:
      enabled: 0
      settings:
        DefaultValueInitialized: true
  userData:
  assetBundleName:
  assetBundleVariant:

Hmm. At face value, this seems to be a Unity specific file. However, one takeaway is the guid which seems to match up with the directory name. Other than the fact that this seems to be some sort of YAML file, there isn’t much else we can learn from this file, and for all intents and purposes, we don’t really need to know much more.

Ok, so we understand what a .unitypackage contains, and how it’s structured. How can we generate one so we can package our SDK with this file format?

Unity allows developers to export any directory from within a project as a unity package. However, it seems that the only way to do this is from within Unity itself. At TestFairy, we love automating as many things as it can. Internally, we lean heavily on Travis-CI to build, and deploy many of our artifacts. In this case, installing Unity on a Travis server, seemed to be a non-starter.

We explored alternative tools to help package our SDK, but we didn’t find anything that worked for us. Armed with the knowledge of how a .unitypacakge is created, we wrote and open-sourced testfairy-unity-asset-packager (ya, we’re not great with naming). This tool will take any directory in a Unity project and bundle it into a .unitypackage.

One concession we had to make was with regards to these .meta files which are needed (and are used to construct the .unitypackage). We decided that we would commit the generated .meta files generated by Unity into our SDK’s repo so that we could use testfairy-unity-asset-packager as part of our build process. A better solution might be to have some tool that can generate the .meta files by passing in some file specific arguments. It doesn’t appear that Unity has released a specification for this file, so if you’re reading this, and are aware of such a tool or library that can generate the .meta files, let us know! We’d love to hear from you!