public static void ConfigureDeployment(string configurationID, bool deploy = false, bool build = false) { string deploymentID; string deployableApplicationDataPath; bool inDeployment = DeploymentBuilder.GetInDeployment( out deploymentID, out deployableApplicationDataPath); JObject config = FindDeployment(configurationID); if (config == null) { return; } // Configure scenes, and load initial scene. string[] scenes = config["scenes"].ToObject <string[]>(); //Debug.Log("DeploymentBuilder: ConfigureDeployment: scenes: " + scenes); if (scenes == null) { Debug.LogError("DeploymentBuilder: ConfigureDeployment: scenes missing from config: " + config); return; } // Make a list of EditorBuilderSettingsScenes for the EditorBuildingSettings.scenes array. List <EditorBuildSettingsScene> editorBuildSettingsScenes = new List <EditorBuildSettingsScene>(); foreach (string scenePath in scenes) { EditorBuildSettingsScene editorBuildSettingsScene = new EditorBuildSettingsScene(scenePath, true); editorBuildSettingsScenes.Add(editorBuildSettingsScene); Debug.Log("editorBuildSettingsScene: " + editorBuildSettingsScene + " scenePath: " + scenePath); } // Set the EditorBuildingSettings.scenes array. EditorBuildSettings.scenes = editorBuildSettingsScenes.ToArray(); //Debug.Log("EditorBuildSettings.scenes: " + EditorBuildSettings.scenes); // Open the initial scene. UnityEngine.SceneManagement.Scene scene = EditorSceneManager.OpenScene(scenes[0]); if (scene == null) { Debug.LogError("DeploymentBuilder: ConfigureDeployment: can't open scene: " + scenes[0]); return; } // Fish out the Bridge. GameObject bridgeObj = GameObject.Find("Bridge"); if (bridgeObj == null) { Debug.LogError("DeploymentBuilder: ConfigureDeployment: Can't find Bridge GameObject in scene: " + scenes[0]); return; } // Configure the Booter, if present. Booter booter = bridgeObj.GetComponent <Booter>(); if (booter != null) { Undo.RecordObject(bridgeObj, "Configure Bridge"); EditorUtility.SetDirty(booter); string bootConfigurationsKey = (string)config["bootConfigurationsKey"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: bootConfigurationsKey: " + bootConfigurationsKey); if (bootConfigurationsKey == null) { bootConfigurationsKey = ""; } booter.bootConfigurationsKey = bootConfigurationsKey; } // Configure the Bridge, which must be present. Bridge bridge = bridgeObj.GetComponent <Bridge>(); if (bridge == null) { Debug.LogError("DeploymentBuilder: ConfigureDeployment: Can't find Bridge component on Bridge GameObject bridgeObj: " + bridgeObj); return; } Undo.RecordObject(bridgeObj, "Configure Bridge"); EditorUtility.SetDirty(bridge); string deployment = (string)config["deployment"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployment: " + deployment); bridge.deployment = deployment; string title = (string)config["title"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: title: " + title); bridge.title = title; string gameID = (string)config["gameID"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: gameID: " + gameID); bridge.gameID = gameID; string url = (string)config["url"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: url: " + url); bridge.url = url; string configuration = (string)config["configuration"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: configuration: " + configuration); bridge.configuration = configuration; #if USE_SOCKETIO && UNITY_EDITOR bool useSocketIO = (bool)config["useSocketIO"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: useSocketIO: " + useSocketIO); bridge.useSocketIO = useSocketIO; string socketIOAddress = (string)config["socketIOAddress"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: socketIOAddress: " + socketIOAddress); bridge.socketIOAddress = socketIOAddress; #endif // Configure the PlayerSettings. string productName = (string)config["productName"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: productName: " + productName); PlayerSettings.productName = productName; BuildTargetGroup buildTargetGroup = Bridge.ToEnum <BuildTargetGroup>(config["buildTargetGroup"]); //Debug.Log("DeploymentBuilder: ConfigureDeployment: buildTargetGroup: " + buildTargetGroup); string bundleIdentifier = (string)config["bundleIdentifier"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: bundleIdentifier: " + bundleIdentifier); PlayerSettings.SetApplicationIdentifier(buildTargetGroup, bundleIdentifier); string defineSymbols = (string)config["defineSymbols"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: defineSymbols: " + defineSymbols); PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defineSymbols); string bundleVersion = (string)config["bundleVersion"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: bundleVersion: " + bundleVersion); PlayerSettings.bundleVersion = bundleVersion; bool virtualRealitySupported = (bool)config["virtualRealitySupported"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: virtualRealitySupported: " + virtualRealitySupported); PlayerSettings.virtualRealitySupported = virtualRealitySupported; // Configure the PlayerSettings for the build target. BuildTarget buildTarget = Bridge.ToEnum <BuildTarget>(config["buildTarget"]); //Debug.Log("DeploymentBuilder: ConfigureDeployment: buildTarget: " + buildTarget); switch (buildTarget) { case BuildTarget.WebGL: { string webGLTemplate = (string)config["webGLTemplate"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: webGLTemplate: " + webGLTemplate); PlayerSettings.WebGL.template = webGLTemplate; break; } case BuildTarget.iOS: { string buildNumber = (string)config["buildNumber"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: buildNumber: " + buildNumber); PlayerSettings.iOS.buildNumber = buildNumber; break; } case BuildTarget.Android: { string sdk = Environment.GetEnvironmentVariable( //"ANDROID_SDK_ROOT" "ANDROID_HOME" ); if (!string.IsNullOrEmpty(sdk)) { EditorPrefs.SetString("AndroidSdkRoot", sdk); //Debug.Log("DeploymentBuilder: ConfigureDeployment: Android sdk: " + sdk); } int bundleVersionCode = (int)config["bundleVersionCode"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: bundleVersionCode: " + bundleVersionCode); PlayerSettings.Android.bundleVersionCode = bundleVersionCode; string keystorePath = (string)config["keystorePath"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: keystorePath: " + keystorePath); PlayerSettings.Android.keystoreName = keystorePath; string keyaliasName = (string)config["keyaliasName"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: keyaliasName: " + keyaliasName); PlayerSettings.Android.keyaliasName = keyaliasName; string keyaliasPass = (string)config["keyaliasPass"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: keyaliasPass: "******"DeploymentBuilder: ConfigureDeployment: Unknown buildTarget: " + buildTarget); return; } } // switch buildTarget EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildTarget); // Make sure all the changes are saved. EditorSceneManager.MarkSceneDirty(scene); EditorSceneManager.SaveScene(scene); AssetDatabase.SaveAssets(); // Copy files around in the deployable project. JArray copyFiles = (JArray)config["copyFiles"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: copyFiles: " + copyFiles); if (copyFiles != null) { foreach (JArray fromToPaths in copyFiles) { string sourcePath = Path.GetFullPath( deployableApplicationDataPath + "/" + (string)fromToPaths[0]); string destPath = Path.GetFullPath( deployableApplicationDataPath + "/" + (string)fromToPaths[1]); CopyTree(sourcePath, destPath, false); } AssetDatabase.Refresh(); } // if copyFiles != null // Deploy this configuration if deploy is enabled. if (deploy) { if (deployment == null) { Debug.Log("DeploymentBuilder: ConfigureDeployment: missing deployment! config: " + config.ToString()); return; } string deploymentsDirectory = (string)config["deploymentsDirectory"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deploymentsDirectory: " + deploymentsDirectory); string rootPath = Path.GetFullPath( deployableApplicationDataPath + "/.."); string deploymentPath = Path.GetFullPath( rootPath + deploymentsDirectory + deployment); //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployment: " + deployment + " deploymentPath: " + deploymentPath); // Clean out the deployment only if we're in the deployable project. if (!inDeployment) { #if false if (Directory.Exists(deploymentPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: deleting old directory deploymentPath: " + deploymentPath); Directory.Delete(deploymentPath, true); } //Debug.Log("DeploymentBuilder: ConfigureDeployment: Creating new directory deploymentPath: " + deploymentPath); Directory.CreateDirectory(deploymentPath); #endif JArray deployClean = (JArray)config["deployClean"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployClean: " + deployClean); if (deployClean != null) { foreach (string item in deployClean) { string destPath = deploymentPath + "/" + item; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployClean: item: " + item); if (File.Exists(destPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: Cleaning file: " + destPath); File.Delete(destPath); } else if (Directory.Exists(destPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: Cleaning directory: " + destPath); Directory.Delete(destPath, true); } string destPathMeta = destPath + ".meta"; //Debug.Log("DeploymentBuilder: ConfigureDeployment: destMetaPath: " + destMetaPath); if (File.Exists(destPathMeta)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: Cleaning file: " + destPathMeta); File.Delete(destPathMeta); } else if (Directory.Exists(destPathMeta)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: Cleaning directory: " + destPathMeta); Directory.Delete(destPathMeta, true); } } } } // Create directories in the deployment project. JArray deployCreateDirectories = (JArray)config["deployCreateDirectories"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployCreateDirectories: " + deployCreateDirectories); if (deployCreateDirectories != null) { foreach (string item in deployCreateDirectories) { string sourcePath; string destPath; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployCreateDirectories: item: " + item); sourcePath = rootPath + "/" + item; destPath = deploymentPath + "/" + item; //Debug.Log("DeploymentBuilder: ConfigureDeployment: Creating directory destPath: " + destPath); if (!Directory.Exists(destPath)) { Directory.CreateDirectory(destPath); } string sourceMetaPath = sourcePath + ".meta"; //Debug.Log("DeploymentBuilder: ConfigureDeployment: sourceMetaPath: " + sourceMetaPath); //Debug.Log("DeploymentBuilder: ConfigureDeployment: sourceMetaPath exists: " + File.Exists(sourceMetaPath)); string destMetaPath = destPath + ".meta"; //Debug.Log("DeploymentBuilder: ConfigureDeployment: destMetaPath: " + destMetaPath); //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployCreateDirectories: sourceMetaPath: " + sourceMetaPath + " destMetaPath: " + destMetaPath + " source file exists: " + File.Exists(sourceMetaPath)); if (File.Exists(sourceMetaPath)) { string sourceMetaPathRelative = RelativeLinkPath(sourceMetaPath, destMetaPath); //Debug.Log("DeploymentBuilder: ConfigureDeployment: Copying directory meta file sourceMetaPath: " + sourceMetaPath + " sourceMetaPathRelative: " + sourceMetaPathRelative + " to destMetaPath: " + destMetaPath); MakeSymbolicLink(sourceMetaPathRelative, destMetaPath); } } } // Copy files into the deployment project. JArray deployCopyFiles = (JArray)config["deployCopyFiles"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployCopyFiles: " + deployCopyFiles); if (deployCopyFiles != null) { foreach (JToken item in deployCopyFiles) { string sourcePath; string destPath; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployCopyFiles: item: " + item); string itemString = (string)item; JArray itemArray = (item is JArray) ? (JArray)item : null; if (itemString != null) { sourcePath = rootPath + "/" + itemString; destPath = deploymentPath + "/" + itemString; } else if (itemArray != null) { sourcePath = rootPath + "/" + (string)itemArray[0]; destPath = deploymentPath + "/" + (string)itemArray[1]; } else { Debug.LogError("DeploymentBuilder: ConfigureDeployment: deployCopyFiles: invalid item: " + item); return; } //Debug.Log("DeploymentBuilder: deployCopyFile: sourcePath: " + sourcePath + " destPath: " + destPath); CopyTree(sourcePath, destPath, true); } } // Symlink files into the deployment project. JArray deployLinkFiles = (JArray)config["deployLinkFiles"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: " + deployLinkFiles); if (deployLinkFiles != null) { foreach (JToken item in deployLinkFiles) { string sourcePath; string destPath; JArray itemArray = (item is JArray) ? (JArray)item : null; string itemString = (itemArray == null) ? (string)item : null; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: item: " + item.Type + " " + item + " itemString: " + itemString + " itemArray: " + itemArray); if (itemString != null) { sourcePath = rootPath + "/" + itemString; destPath = deploymentPath + "/" + itemString; } else if (itemArray != null) { sourcePath = rootPath + "/" + (string)itemArray[0]; destPath = deploymentPath + "/" + (string)itemArray[1]; } else { Debug.LogError("DeploymentBuilder: ConfigureDeployment: invalid item: " + item); return; } if (Directory.Exists(destPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: deleting existing directoy destPath: " + destPath); Directory.Delete(destPath, true); } else if (File.Exists(destPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: deleting existing file destPath: " + destPath); File.Delete(destPath); } if (Directory.Exists(sourcePath) || File.Exists(sourcePath)) { string sourcePathRelative = RelativeLinkPath(sourcePath, destPath); string destParentPath = Directory.GetParent(destPath).FullName; bool destParentDirectoryExists = Directory.Exists(destParentPath); //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: destPath: " + destPath + " destParentPath: " + destParentPath + " destParentDirectoryExists: " + destParentDirectoryExists); if (!destParentDirectoryExists) { // TODO: Link .meta files in intermediate created directories. Directory.CreateDirectory(destParentPath); } //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: linking sourcePath: " + sourcePath + " sourcePathRelative: " + sourcePathRelative + " to destPath " + destPath); MakeSymbolicLink(sourcePathRelative, destPath); string sourceMetaPath = sourcePath + ".meta"; string sourceMetaPathRelative = sourcePathRelative + ".meta"; bool sourceMetaFileExists = File.Exists(sourceMetaPath); //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: sourceMetaPath: " + sourceMetaPath + " sourceMetaPathRelative: " + sourceMetaPathRelative + " sourceMetaFileExists: " + sourceMetaFileExists); if (sourceMetaFileExists) { string destMetaPath = destPath + ".meta"; //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: copying meta file from sourceMetaPath: " + sourceMetaPath + " sourceMetaPathRelative: " + sourceMetaPathRelative + " to destMetaPath: " + destMetaPath); if (Directory.Exists(destMetaPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: deleting existing meta directoy destMetaPath: " + destMetaPath); Directory.Delete(destMetaPath, true); } else if (File.Exists(destMetaPath)) { //Debug.Log("DeploymentBuilder: ConfigureDeployment: deployLinkFiles: deleting existing meta file destMetaPath: " + destMetaPath); File.Delete(destMetaPath); } MakeSymbolicLink(sourceMetaPathRelative, destMetaPath); } } else { Debug.LogError("DeploymentBuilder: ConfigureDeployment: missing sourcePath: " + sourcePath); } } } } // if deploy // Build this configuration if build is enabled. if (build) { BuildOptions buildOptions = Bridge.ToEnumMask <BuildOptions>(config["buildOptions"]); //Debug.Log("DeploymentBuilder: ConfigureDeployment: buildOptions: " + buildOptions); string buildLocation = (string)config["buildLocation"]; //Debug.Log("DeploymentBuilder: ConfigureDeployment: buildLocation: " + buildLocation); // Switch to the build target. //EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildTarget); BuildReport buildReport = BuildPipeline.BuildPlayer( scenes, buildLocation, buildTarget, buildOptions); if (buildReport.summary.result != BuildResult.Succeeded) { Debug.Log("DeploymentBuilder: "); throw new Exception("Build failed!"); } } // if build }
private void OnGUI() { string applicationDataPath = Application.dataPath; JObject currentDeploymentConfiguration = null; JObject selectedDeploymentConfiguration = null; string deploymentID; string deployableApplicationDataPath; bool inDeployment = DeploymentBuilder.GetInDeployment( out deploymentID, out deployableApplicationDataPath); string selectedDeploymentConfigurationID = EditorPrefs.GetString( "Deployment_selectedDeploymentConfigurationID", ""); string currentDeploymentConfigurationID = EditorPrefs.GetString( "Deployment_currentDeploymentConfigurationID", ""); GUILayout.Label( "UnityJS Deployment Builder Window"); GUILayout.Space(5); if (GUILayout.Button( "\nReload Deployment Configurations\n")) { DeploymentBuilder.ReloadDeploymentConfigurations(); } JArray deploymentConfigurations = DeploymentBuilder.GetDeploymentConfigurations(); GUILayout.Space(5); if (inDeployment) { selectedDeploymentConfigurationID = currentDeploymentConfigurationID = deploymentID; } foreach (JObject deploymentConfiguration in deploymentConfigurations) { string id = (string)deploymentConfiguration["id"]; if (id == currentDeploymentConfigurationID) { currentDeploymentConfiguration = deploymentConfiguration; selectedDeploymentConfiguration = currentDeploymentConfiguration; break; } } if (inDeployment) { GUILayout.Label( "This is the deployment project: " + currentDeploymentConfigurationID); GUILayout.Space(5); if (currentDeploymentConfiguration == null) { GUILayout.Label( "A deployment with that id is missing from the DeploymentConfigurations file!"); } else { string[] scenes = currentDeploymentConfiguration["scenes"].ToObject <string[]>(); string scenePath = (scenes.Length > 0) ? scenes[0] : ""; UnityEngine.SceneManagement.Scene activeScene = EditorSceneManager.GetActiveScene(); if ((activeScene == null) || (activeScene.path != scenePath)) { if (GUILayout.Button( "\nLoad Scene:\n" + scenePath + "\n")) { UnityEngine.SceneManagement.Scene scene = EditorSceneManager.OpenScene(scenePath); Debug.Log("Opened scenePath: " + scenePath + " scene: " + scene); } } else { if (GUILayout.Button( "\nBuild Scene:\n" + scenePath + "\n")) { DeploymentBuilder.ConfigureDeployment(currentDeploymentConfigurationID, false, true); } } } GUILayout.Space(5); } else { GUILayout.Label( "This is the deployable project, not a deployment project."); GUILayout.Label( "Select a deployment configuration:"); scrollPos1 = EditorGUILayout.BeginScrollView( scrollPos1, GUILayout.ExpandHeight(true), GUILayout.MaxHeight(maxScrollViewHeight1)); foreach (JObject deploymentConfiguration in deploymentConfigurations) { string id = (string)deploymentConfiguration["id"]; bool current = id == currentDeploymentConfigurationID; bool selected = id == selectedDeploymentConfigurationID; string title = " " + id + ": " + (string)deploymentConfiguration["title"] + (current ? " (current)" : ""); if (selected) { selectedDeploymentConfiguration = deploymentConfiguration; } if (GUILayout.Button( title, current ? (selected ? listFontStyleCurrentSelected : listFontStyleCurrent) : (selected ? listFontStyleSelected : listFontStyle))) { EditorPrefs.SetString("Deployment_selectedDeploymentConfigurationID", id); } } EditorGUILayout.EndScrollView(); GUILayout.Space(5); } if (selectedDeploymentConfiguration == null) { GUILayout.Label( "Select a deployment configuration to see its properties."); } else { string title = (string)selectedDeploymentConfiguration["title"]; string applicationName = (string)selectedDeploymentConfiguration["applicationName"]; string location = (string)selectedDeploymentConfiguration["location"]; string buildTarget = (string)selectedDeploymentConfiguration["buildTarget"]; string buildTargetGroup = (string)selectedDeploymentConfiguration["buildTargetGroup"]; string virtualRealitySupported = (string)selectedDeploymentConfiguration["virtualRealitySupported"]; GUILayout.Label( "Selected Deployment Configuration" + ((selectedDeploymentConfiguration == currentDeploymentConfiguration) ? " (current):\n" : " (not current):\n") + " ID: " + selectedDeploymentConfigurationID + "\n" + " Title: " + title + "\n" + " Application Name: " + applicationName + "\n" + " Location: " + location + "\n" + " Build Target: " + buildTarget + "\n" + " Build Target Group: " + buildTargetGroup + "\n" + " Virtual Reality Supported: " + virtualRealitySupported + "\n" + ""); GUILayout.Space(5); if (selectedDeploymentConfiguration != currentDeploymentConfiguration) { if (GUILayout.Button( "\nChange current deployment configuration to:\n\n" + "ID: " + selectedDeploymentConfigurationID + "\n" + "Title: " + (string)selectedDeploymentConfiguration["title"] + "\n")) { EditorPrefs.SetString("Deployment_currentDeploymentConfigurationID", selectedDeploymentConfigurationID); } GUILayout.Space(5); } else { if (GUILayout.Button( "\nConfigure and Deploy Current Deployment Configuration\n")) { DeploymentBuilder.ConfigureDeployment(currentDeploymentConfigurationID, true, false); } GUILayout.Space(5); } } GUILayout.Space(5); GUILayout.Label( (currentDeploymentConfiguration == null) ? "All Deployment Configurations:" : "Deployment Configuration for " + currentDeploymentConfigurationID + ":"); scrollPos2 = EditorGUILayout.BeginScrollView( scrollPos2, GUILayout.ExpandHeight(true), GUILayout.MaxHeight(maxScrollViewHeight2)); string json = (currentDeploymentConfiguration != null) ? JsonConvert.SerializeObject( currentDeploymentConfiguration, Formatting.Indented) : ((deploymentConfigurations != null) ? JsonConvert.SerializeObject( deploymentConfigurations, Formatting.Indented) : "undefined"); GUILayout.Label( json); EditorGUILayout.EndScrollView(); GUILayout.FlexibleSpace(); }