Unity3D Conditional Device Compilation By Scenes

Recently I posted at the Unity3D forum in regard to how one can create a single project and compile multiple device and platform builds within this context. My goal here is simply to reduce having multiple projects for a single Unity3d application.

On my second cup of coffee here and hope I make sense with my questions here.

After watching the fantastic Smuggle Truck design/build discussions here:
I was perplexed by how they created the iPad/iPhone/Mac OS conditional compilation build all from a single project. Only those assets referenced for that build are baked into the final project that is then sent to XCode.

I’m aware of the preprocessor flags (http://unity3d.com/support/documenta…mpilation.html). I also understand how to use them.

I guess the hurdle(s) I haven’t figured out yet are the following.

1. How does one condition the build between UNITY_IPHONE and UNITY_IPAD? Note: there isn’t any UNITY_IPAD define that I’m aware of. Within the Unity editor it is not possible to pass in custom preprocessor defines globally. They are scoped per-script. I see the command line option of “-executeMethod …” (http://unity3d.com/support/documenta…Arguments.html) Perhaps that is the magic sauce?

2. How did they conditionally include only unique assets to that particular build? For example, Mac OS X textures would be a higher resolution than those for the iPad and iPhone. Perhaps, this will be answered in question one.

Anyone have any ideas or other forum links that I may have missed?
Note, I have seen this: http://forum.unity3d.com/threads/171…al+Compilation

Well here is a basic solution that is created by scene. By scene means that you have to create a different scene for each device but give them the same name. As seen in the first picture here.

Let me just state for the record that this solution would work perfectly but it is less than ideal. I am posting this to merely explain how to conditionally gather assets into a final deployment as well as to isolate resources per build. I believe the ideal solution would be to use asset bundles. I will cover that in a new blog entry in a few days/weeks as I figure it out as well.

I am going to provide a script at the bottom of this article and a zip file containing the magic mixture to easily integrate this beast into your project. Integrating this script is easy. Simply uncompress the zip file and place the “MonkeyPrism” folder into the root of your project.

Once you have the C-Sharp editor object installed you should be able to run the basic build process using the menu system or shortcut keys as documented within the C-Sharp code.

Download the file here.

Everyone: This script requires Unity Pro and it is setup to build for (iPhone, iPad, Mac OS Universal and Windows).
PC Users: Take note that I used the “/” in my script.

View Code CSHARP
using System;
using UnityEditor;
using UnityEngine;
/// <summary>
/// A C# build object demonstrating a dynamic build process for Unity 3D.
/// This script requires you to organize your scenes by device and platform as follows:
///		SCENES_LOC / {iphone, ipad, macos, pc} / {your scenes}
///		i.e.	Assets/Scenes/iphone/scene0.unity
///				Assets/Scenes/iphone/scene1.unity
/// Please note: this is not perfect and honestly, I'm looking into an asset bundle
/// solution as well here.  I just wanted to figure out if there was a better solution.
/// Version 1.0
/// April 29, 2011
/// License:  Free to use and modify.
/// </summary>
public class MonkeyPrismBuild {
	//TODO: place your core scenes location here.  (relative to the already loaded project)
	private const string SCENES_LOC = "Assets/Scenes/";
	//TODO: place your scenes into this array.
	private static string[] myScenes = { 
		"home.unity" }; /*, "levelselect.unity", 
		"game.unity", "credits.unity" };*/
		iPhone = 0, iPad, MacOS, PC
	 * Make sure uniqueBuildNames maps with the enum above and take note of the GetScenesByBuildType method.
	 * Also: make sure that these names match with directories under your SCENES_LOC.
	private static string[] uniqueBuildNames = {"iphone","ipad","macos","pc"};
	[MenuItem ("Tools/Build/iPhone #&i")] //press shift+alt+i
	public static void PerformBuildIPHONE() {
		Debug.Log("Building iPhone version");
	[MenuItem ("Tools/Build/iPad #&p")] //press shift+alt+p
	public static void PerformBuildIPAD() {
		Debug.Log("Building iPad version");
	[MenuItem ("Tools/Build/Mac OS #&m")] //press shift+alt+m
	public static void PerformBuildMACOS() {
		Debug.Log("Building Universal Mac OS version");
	[MenuItem ("Tools/Build/PC #&c")] //press shift+alt+c
	public static void PerformBuildPC() {
		Debug.Log("Building Windows PC version");
	private static string[] GetScenesByBuildType(MP_BUILD_TYPE type, ref string buildDir) {
		int len = myScenes.Length;
		string[] scenes = new string[len];
		//string buildDir = null;
		switch (type) {
			case MP_BUILD_TYPE.iPad:
				buildDir = uniqueBuildNames[(int)MP_BUILD_TYPE.iPad];
			case MP_BUILD_TYPE.iPhone:
				buildDir = uniqueBuildNames[(int)MP_BUILD_TYPE.iPhone];
			case MP_BUILD_TYPE.MacOS:
				buildDir = uniqueBuildNames[(int)MP_BUILD_TYPE.MacOS];
				buildDir = uniqueBuildNames[(int)MP_BUILD_TYPE.PC];
		} //end switch;
		if (buildDir == null || buildDir.Length < 1) 
			throw new Exception("Invalid MP_BUILD_TYPE::BuildType Specified.  Please visit the MPBuild.cs script to resolve.");
			scenes[i] = SCENES_LOC + buildDir + "/" + myScenes[i];
		return scenes;
	private static void RunBuild(MP_BUILD_TYPE type) {
		string buildDir = null;
		string[] scenes = GetScenesByBuildType(type, ref buildDir);
		switch (type) {
			case MP_BUILD_TYPE.iPad:
			case MP_BUILD_TYPE.iPhone:
				BuildPipeline.BuildPlayer(scenes, buildDir, BuildTarget.iPhone, BuildOptions.None);
			case MP_BUILD_TYPE.MacOS:
				BuildPipeline.BuildPlayer(scenes, buildDir, BuildTarget.StandaloneOSXUniversal, BuildOptions.None);
				BuildPipeline.BuildPlayer(scenes, buildDir, BuildTarget.StandaloneWindows, BuildOptions.None);
		} //end switch;


  1. No comments yet.
(will not be published)

  1. No trackbacks yet.