/// <summary> /// Configures the project to prepare for building the specified scenes in an instant app. /// </summary> public static void ConfigureProject(string[] scenesInBuild) { var requiredPolicies = PlayInstantSettingPolicy.GetRequiredPolicies(); foreach (var policy in requiredPolicies) { var policyChangeCompleted = policy.ChangeState(); if (!policyChangeCompleted) { throw new Exception(string.Format("Failed to change policy: {0}", policy.Name)); } } SetTargetArchitectures(); var manifestUpdater = AndroidManifestHelper.GetAndroidManifestUpdater(); var errorMessage = manifestUpdater.SwitchToInstant(null); if (errorMessage != null) { throw new Exception(string.Format("Error updating AndroidManifest.xml: {0}", errorMessage)); } PlayInstantBuildConfiguration.AddScriptingDefineSymbol( PlaySignatureVerifier.SkipVerifyGooglePlayServicesScriptingDefineSymbol); PlayInstantBuildConfiguration.SaveConfiguration("", scenesInBuild, ""); PlayInstantBuildConfiguration.SetInstantBuildType(); }
/// <summary> /// Read and update the window with most recent build configuration values. /// </summary> void ReadFromBuildConfiguration() { _isInstant = PlayInstantBuildConfiguration.IsInstantBuildType(); _instantUrl = PlayInstantBuildConfiguration.InstantUrl; _scenesInBuild = GetScenesInBuildAsString(PlayInstantBuildConfiguration.ScenesInBuild); _assetBundleManifestPath = PlayInstantBuildConfiguration.AssetBundleManifestPath; }
/// <summary> /// Displays an error dialog if there is an issue that would prevent a build from succeeding. /// </summary> /// <returns>True if all prerequisites are met, or false if one failed.</returns> public static bool CheckBuildPrerequisites() { if (!Directory.Exists(AndroidSdkManager.AndroidSdkRoot)) { DisplayBuildError( "Failed to locate the Android SDK. Check Preferences -> External Tools to set the path."); return(false); } try { var ignored = JavaUtilities.JavaBinaryPath; } catch (JavaUtilities.ToolNotFoundException) { DisplayBuildError( "Failed to locate the Java JDK. Check Preferences -> External Tools to set the path."); return(false); } if (!PlayInstantBuildConfiguration.IsInstantBuildType()) { Debug.LogError("Build halted since selected build type is \"Installed\""); var message = string.Format( "The currently selected Android build type is \"Installed\".\n\n" + "Click \"{0}\" to open the \"{1}\" window where the build type can be changed to \"Instant\".", WindowUtils.OkButtonText, BuildSettingsWindow.WindowTitle); if (DisplayBuildErrorDialog(message)) { BuildSettingsWindow.ShowWindow(); } return(false); } var failedPolicies = new List <string>(PlayInstantSettingPolicy.GetRequiredPolicies() .Where(policy => !policy.IsCorrectState()) .Select(policy => policy.Name)); if (failedPolicies.Count > 0) { Debug.LogErrorFormat("Build halted due to incompatible settings: {0}", string.Join(", ", failedPolicies.ToArray())); var message = string.Format( "{0}\n\nClick \"{1}\" to open the settings window and make required changes.", string.Join("\n\n", failedPolicies.ToArray()), WindowUtils.OkButtonText); if (DisplayBuildErrorDialog(message)) { PlayerSettingsWindow.ShowWindow(); } return(false); } return(true); }
private void SelectPlatformInstant() { Uri uri = null; _instantUrl = _instantUrl == null ? string.Empty : _instantUrl.Trim(); if (_instantUrl.Length > 0) { try { // TODO: allow port numbers? allow query parameters? uri = new Uri(_instantUrl); } catch (Exception ex) { DisplayUrlError(string.Format("The URL is invalid: {0}", ex.Message)); return; } if (uri.Scheme.ToLower() != "https") { DisplayUrlError("The URL scheme should be \"https\""); return; } if (string.IsNullOrEmpty(uri.Host)) { DisplayUrlError("If a URL is provided, the host must be specified"); return; } } var errorMessage = _androidManifestUpdater.SwitchToInstant(uri); if (errorMessage != null) { var message = string.Format("Error updating AndroidManifest.xml: {0}", errorMessage); Debug.LogError(message); EditorUtility.DisplayDialog("Error Saving", message, "OK"); return; } var scenesInBuild = _scenesInBuild.Split(',').Where(s => s.Trim().Length > 0).Select(s => s.Trim()).ToArray(); _scenesInBuild = GetScenesInBuildAsString(scenesInBuild); _assetBundleManifestPath = _assetBundleManifestPath.Trim(); PlayInstantBuildConfiguration.SaveConfiguration(_instantUrl, scenesInBuild, _assetBundleManifestPath); PlayInstantBuildConfiguration.SetInstantBuildType(); // If a TextField is in focus, it won't update to reflect the Trim(). So reassign focus to controlID 0. GUIUtility.keyboardControl = 0; Repaint(); }
private bool IsAnyFieldChanged() { if (_isInstant) { return(!PlayInstantBuildConfiguration.IsInstantBuildType() || _instantUrl != PlayInstantBuildConfiguration.InstantUrl || _scenesInBuild != GetScenesInBuildAsString(PlayInstantBuildConfiguration.ScenesInBuild) || _assetBundleManifestPath != PlayInstantBuildConfiguration.AssetBundleManifestPath); } // If changing the build type to "Installed", then we don't care about the other fields return(PlayInstantBuildConfiguration.IsInstantBuildType()); }
private void SelectPlatformInstant() { Uri uri = null; _instantUrl = _instantUrl == null ? string.Empty : _instantUrl.Trim(); if (_instantUrl.Length > 0) { try { // TODO: allow port numbers? allow query parameters? uri = new Uri(_instantUrl); } catch (Exception ex) { DisplayUrlError(string.Format("The URL is invalid: {0}", ex.Message)); return; } if (uri.Scheme.ToLower() != "https") { DisplayUrlError("The URL scheme should be \"https\""); return; } if (string.IsNullOrEmpty(uri.Host)) { DisplayUrlError("If a URL is provided, the host must be specified"); return; } } var errorMessage = _androidManifestUpdater.SwitchToInstant(uri); if (errorMessage == null) { PlayInstantBuildConfiguration.DefinePlayInstantScriptingSymbol(); PlayInstantBuildConfiguration.SetInstantUrl(_instantUrl); Close(); } else { var message = string.Format("Error updating AndroidManifest.xml: {0}", errorMessage); Debug.LogError(message); EditorUtility.DisplayDialog("Error Saving", message, "OK"); } }
private void SelectPlatformInstant() { string instantUrlError; var uri = GetInstantUri(_instantUrl, out instantUrlError); if (instantUrlError != null) { Debug.LogErrorFormat("Invalid URL: {0}", instantUrlError); EditorUtility.DisplayDialog("Invalid URL", instantUrlError, WindowUtils.OkButtonText); return; } // The URL is valid, so save any clean-ups performed by conversion through Uri, e.g. HTTPS->https. _instantUrl = uri == null ? string.Empty : uri.ToString(); var errorMessage = _androidManifestUpdater.SwitchToInstant(uri); if (errorMessage != null) { var message = string.Format("Error updating AndroidManifest.xml: {0}", errorMessage); Debug.LogError(message); EditorUtility.DisplayDialog("Error Saving", message, WindowUtils.OkButtonText); return; } var scenesInBuild = _scenesInBuild.Split(',').Where(s => s.Trim().Length > 0).Select(s => s.Trim()).ToArray(); _scenesInBuild = GetScenesInBuildAsString(scenesInBuild); _assetBundleManifestPath = _assetBundleManifestPath.Trim(); PlayInstantBuildConfiguration.SaveConfiguration(_instantUrl, scenesInBuild, _assetBundleManifestPath); PlayInstantBuildConfiguration.SetInstantBuildType(); Debug.Log("Saved Play Instant Build Settings."); // If a TextField is in focus, it won't update to reflect the Trim(). So reassign focus to controlID 0. GUIUtility.keyboardControl = 0; Repaint(); }
private static bool Build(BuildPlayerOptions buildPlayerOptions) { if (!PlayInstantBuildConfiguration.IsInstantBuildType()) { Debug.LogError("Build halted since selected build type is \"Installed\""); var message = string.Format( "The currently selected Android build type is \"Installed\".\n\n" + "Click \"OK\" to open the \"{0}\" window where the build type can be changed to \"Instant\".", BuildSettingsWindow.WindowTitle); if (DisplayBuildErrorDialog(message)) { BuildSettingsWindow.ShowWindow(); } return(false); } var failedPolicies = new List <string>(PlayInstantSettingPolicy.GetRequiredPolicies() .Where(policy => !policy.IsCorrectState()) .Select(policy => policy.Name)); if (failedPolicies.Count > 0) { Debug.LogErrorFormat("Build halted due to incompatible settings: {0}", string.Join(", ", failedPolicies.ToArray())); var message = string.Format( "{0}\n\nClick \"OK\" to open the settings window and make required changes.", string.Join("\n\n", failedPolicies.ToArray())); if (DisplayBuildErrorDialog(message)) { PlayerSettingsWindow.ShowWindow(); } return(false); } var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions); #if UNITY_2018_1_OR_NEWER switch (buildReport.summary.result) { case BuildResult.Cancelled: Debug.Log("Build cancelled"); return(false); case BuildResult.Succeeded: // BuildPlayer can fail and still return BuildResult.Succeeded so detect by checking totalErrors. if (buildReport.summary.totalErrors > 0) { // No need to display a message since Unity will already have done this. return(false); } // Actual success. return(true); case BuildResult.Failed: LogError(string.Format("Build failed with {0} error(s)", buildReport.summary.totalErrors)); return(false); default: LogError("Build failed with unknown error"); return(false); } #else if (string.IsNullOrEmpty(buildReport)) { return(true); } // Check for intended build cancellation. if (buildReport == "Building Player was cancelled") { Debug.Log(buildReport); } else { LogError(buildReport); } return(false); #endif }
private void Awake() { _isInstant = PlayInstantBuildConfiguration.IsPlayInstantScriptingSymbolDefined(); _instantUrl = PlayInstantBuildConfiguration.GetInstantUrl(); }
private void SelectPlatformInstalled() { PlayInstantBuildConfiguration.UndefinePlayInstantScriptingSymbol(); _androidManifestUpdater.SwitchToInstalled(); Close(); }
private void SelectPlatformInstalled() { PlayInstantBuildConfiguration.SetInstalledBuildType(); _androidManifestUpdater.SwitchToInstalled(); Debug.Log("Switched to Android Build Type \"Installed\"."); }
private void SelectPlatformInstalled() { PlayInstantBuildConfiguration.SetInstalledBuildType(); _androidManifestUpdater.SwitchToInstalled(); }
public static void BuildAndRun() { if (!PlayInstantBuildConfiguration.IsPlayInstantScriptingSymbolDefined()) { Debug.LogError("Build and Run halted since selected platform is Installed"); const string message = "The currently selected Android Platform is \"Installed\".\n\n" + "Click \"OK\" to open the \"Configure Instant or Installed\" " + "window where the platform can be changed to \"Instant\"."; if (EditorUtility.DisplayDialog(BuildAndRunErrorTitle, message, OkButtonText, CancelButtonText)) { PlayInstantSettingsWindow.ShowWindow(); } return; } var jarPath = Path.Combine(AndroidSdkManager.AndroidSdkRoot, InstantAppsJarPath); if (!File.Exists(jarPath)) { Debug.LogErrorFormat("Build and Run failed to locate ia.jar file at: {0}", jarPath); var message = string.Format( "Failed to locate version 1.2 or later of the {0}.\n\nClick \"OK\" to install the {0}.", PlayInstantSdkInstaller.InstantAppsSdkName); if (EditorUtility.DisplayDialog(BuildAndRunErrorTitle, message, OkButtonText, CancelButtonText)) { PlayInstantSdkInstaller.SetUp(); } return; } var failedPolicies = new List <string>(PlayInstantSettingPolicy.GetRequiredPolicies() .Where(policy => !policy.IsCorrectState()) .Select(policy => policy.Name)); if (failedPolicies.Count > 0) { Debug.LogErrorFormat("Build and Run halted due to incompatible settings: {0}", string.Join(", ", failedPolicies.ToArray())); var message = string.Format( "{0}\n\nClick \"OK\" to open the settings window and make required changes.", string.Join("\n\n", failedPolicies.ToArray())); if (EditorUtility.DisplayDialog(BuildAndRunErrorTitle, message, OkButtonText, CancelButtonText)) { PlayerAndBuildSettingsWindow.ShowWindow(); } return; } var apkPath = Path.Combine(Path.GetTempPath(), "temp.apk"); Debug.LogFormat("Build and Run package location: {0}", apkPath); var buildPlayerOptions = CreateBuildPlayerOptions(apkPath); #if UNITY_2018_1_OR_NEWER var buildReport = BuildPipeline.BuildPlayer(buildPlayerOptions); switch (buildReport.summary.result) { case BuildResult.Cancelled: Debug.Log("Build cancelled"); return; case BuildResult.Succeeded: // BuildPlayer can fail and still return BuildResult.Succeeded so detect by checking totalErrors. if (buildReport.summary.totalErrors > 0) { // No need to display a message since Unity will already have done this. return; } // Actual success: continue on to the run step. break; case BuildResult.Failed: LogError(string.Format("Build failed with {0} error(s)", buildReport.summary.totalErrors)); return; default: LogError("Build failed with unknown error"); return; } #else var buildPlayerResult = BuildPipeline.BuildPlayer(buildPlayerOptions); if (!string.IsNullOrEmpty(buildPlayerResult)) { // Check for intended build cancellation. if (buildPlayerResult == "Building Player was cancelled") { Debug.Log(buildPlayerResult); } else { LogError(buildPlayerResult); } return; } #endif var window = PostBuildCommandLineDialog.CreateDialog("Install and run app"); window.modal = false; window.summaryText = "Installing app on device"; window.bodyText = "The APK built successfully. Waiting for scripts to reload...\n"; window.autoScrollToBottom = true; window.CommandLineParams = new CommandLineParameters() { FileName = JavaUtilities.JavaBinaryPath, Arguments = string.Format("-jar {0} run {1}", jarPath, apkPath), }; window.CommandLineParams.AddEnvironmentVariable( AndroidSdkManager.AndroidHome, AndroidSdkManager.AndroidSdkRoot); window.Show(); }