.Nam Myoho Renghe Kyo.
[HowTo] – Post Process Building in Unity3D

I have been talking about writing native Unity3D plugins ( android, iOS ). When building native plugins for Android, you dont have to do much after building your Unity3D app. The JAR gets called and you are on your way. On the iOS side however, there is much more than meets the eye. Unity3D, when building for iOS, creates an Objective-C project, from which you can build your iOS app.

In my previous post on native iOS plugins i have talked about subclassing the UnityAppController and extending that functionality. It works great if you are not implementing other Unity3D plugins like Vuforia, which does its own subclassing of the UnityAppController files. Thus your own subclass will not work in this instance. Except if you would 1. incorporate the Vuforia codes in your own subclass OR 2. subclass the Vuforia AppController subclass. But don’t panic. There is another way to get around plugin subclassing.


Unity3D PostProcessBuild Attribute.
Unity has build in support for method attributes. For a complete list of attributes you can go here and here. One of these handy dandy attributes is called [PostProcessBuild]. When using this attribute, Unity3D will take that method and will call it after Unity3D has build the application or project. So why would this be good in our case ? Well, let’s take a step back and think of our process in building native iOS plugins. In the previous described demo we had the following steps to take:

  1. build your plugin.
  2. build your Unity3D project with your plugin incorporated.
  3. Open your xCode project
  4. Subclass the UnityAppController
  5. Build your xCode project.

As you can see, after building an iOS project you will have to go into that project and do some more coding. Ideally you want to not go back into any project, after the unity build, and go coding some more. What you would like to have is for Unity to do that extra coding for you. And it can! using the PostProcessBuild attribute.

So how does this work ?
Heres a little example script of how this class would look.

using UnityEngine;
using UnityEditor.Callbacks;
using UnityEditor;

public class PostBuilder : MonoBehaviour {

   public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
      //Place your post building code here.

It’s pretty straight forward.

So imagine your would wait until Unity3D would be ready with the xCode project build.
Then you would open the UnityAppController files, insert your own plugin code with regexp or a simular tech and save them back again.
Your xCode project would be ready to go without you having to handcode/insert everything in that project.
Win-win situation and everybody’s happy!

There are a few pointers to point out here:

  1. These classes/scripts have to reside inside an “Editor” folder. This folder can be directly underneath the “Assets” folder, but can also be underneath other folders. Unity3D will look for the “Editor” folders and will execute the scripts as needed. For making plugins i would recommend making a folder with plugin name underneath the “Assets” folder and place your “Editor” folder underneath that, so that your PostBuilding scripts will be neatly tucked away in an orderly fashion.
  2. You can set the call order of the PostProcess build attributes by changing the “1” to a higher number -> [PostProcessBuildAttribute(100)]. The default Unity3D uses, if not filled, is “1“. This feature is exceptionally handy when you need to ensure other PostProcess build scripts are executed first, before your code does.
  3. As Unity3D uses C# you can do whatever you want! Even do stuff on OS level if needed. Remember that!
  4. Because most native Android plugins don’t really need this kind of code injection, ensure that this script will only fire for iOS build.
using UnityEngine;
using UnityEditor.Callbacks;
using UnityEditor;

public class CameraPostBuilder : MonoBehaviour {

#if UNITY_IOS // <------ !
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {

#endif   // <------ !

Thats it for today.

Happy coding!

Comments are closed.