How to automatically run code before a build?

Hey everyone,

I’m working on getting a simple build versioning system in place that will basically store a version number in a game object and allow me to display the number during the game. This works, but it required me to create a menu item called “Increment Build Number” and I have to manually run it whenever I create a build.

I know there is a PostprocessPlayer functionality to do things after a build has occurred, but is there any way to run some code right before a build takes place? If so, I could just automatically increment my build number there instead of doing it manually.

You should write your own build script for this. Recently I did exactly what you wanted, showing a version in the game. I generate a file in “Resources” folder which contains version number. Then in game I open this file as text asset and get version number. I generate version according to build date and time, so I don’t need to increment it automatically. But with some logic change that can also be done. Read the last value, increment and save…ect.

These are in BuildScript.cs

BuildClient method:

[MenuItem("Inspire13/Build Test Client #F5")]
public static void BuildClient() 
{
	//KillClients(); // You can kill the running processes here before build.
	SignVersionFile();
	UnityEngine.Debug.Log("Building Client, Directory: " + mClientBuildDirectory);

	try
	{
		PlayerSettings.productName = "TestClient";
		string[] scenes = new string[] { "Assets/_Scenes/Level1.unity", "Assets/_Scenes/Level2" };

		// Build player
		string fileFullPath = mClientBuildDirectory + "/" + mClientBinaryName + ".exe";
		BuildPipeline.BuildPlayer(scenes, fileFullPath, BuildTarget.StandaloneWindows, BuildOptions.Development);

		UnityEngine.Debug.Log("Built!, File: " + fileFullPath);
	}
	catch (Exception e)
	{
		UnityEngine.Debug.LogException(e);
	}     
}

Don’t mind the local variables “mClientBuildDirectory, mClientBinaryName…ect”

And here is my version file generator method
SignVersionFile method:

static void SignVersionFile() 
{
	UnityEngine.Debug.Log("Signing version file...");

	try
	{
		string versionFilePath = Application.dataPath + "/Resources/" + VersionFile;

		// Writes with UTF-8 without BOM (byte order mark)
		using (StreamWriter writer = new StreamWriter(versionFilePath))
		{
			string versionDate = DateTime.Now.ToString("ddMM-HHmm", CultureInfo.InvariantCulture);
			string versionLine = String.Format("{0}.{1}.{2}", MainVersion, SubVersion, versionDate);
			writer.Write(versionLine);
		}

		AssetDatabase.Refresh();
		UnityEngine.Debug.Log("Signed!");
	}
	catch (Exception e)
	{
		UnityEngine.Debug.LogException(e);
	}
}

If you don’t want to write your own build script, you can do the similar thing with PostProcessSceneAttribute: http://docs.unity3d.com/412/Documentation/ScriptReference/PostProcessSceneAttribute.html

For anyone looking into this today, you can now implement, IPreprocessBuildWithReport, to receive a callback before the build is started.

Here is the example provided on the unity documentation:

using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;

class MyCustomBuildProcessor : IPreprocessBuildWithReport
{
    public int callbackOrder { get { return 0; } }
    public void OnPreprocessBuild(BuildReport report)
    {
        Debug.Log("MyCustomBuildProcessor.OnPreprocessBuild for target " + 
        	report.summary.platform + " at path " + report.summary.outputPath);
    }
}