Skip to content

Instantly share code, notes, and snippets.

@Deepscorn
Last active March 4, 2020 13:45
Show Gist options
  • Select an option

  • Save Deepscorn/a1f894738939e4384a340be48879ab77 to your computer and use it in GitHub Desktop.

Select an option

Save Deepscorn/a1f894738939e4384a340be48879ab77 to your computer and use it in GitHub Desktop.
Unity: export android project, then build it
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class Builder
{
[MenuItem("Tools/Test")]
public static void Test()
{
var options = new BuildPlayerOptions
{
locationPathName = Env.AndroidProjectPath,
target = BuildTarget.Android,
options = BuildOptions.AcceptExternalModificationsToPlayer
};
BuildPipeline.BuildPlayer(options);
GradleHelper.Run(Env.AndroidProjectPath, "assembleDebug");
}
[MenuItem("Tools/AssetDatabase Refresh")]
public static void AssetDatabaseRefresh()
{
AssetDatabase.Refresh();
}
}
public static class Env
{
private static string GetUnityPath(params string[] fileSystemEntries)
{
// example: C:\Program Files\Unity\Hub\Editor\2019.3.2f1\Editor
var unityDir = AppDomain.CurrentDomain.BaseDirectory;
return Path.GetFullPath(unityDir + "/" + string.Join("/", fileSystemEntries));
}
private static string JavaPath => GetEditorPref("JdkPath");
public static string JavaExePath => Path.Combine(JavaPath, "bin", "java");
private static string GradlePath =>
GetUnityPath("Data", "PlaybackEngines", "AndroidPlayer", "Tools", "gradle", "lib");
public static string GradleExePath =>
Directory.EnumerateFileSystemEntries(GradlePath, "gradle-launcher-*.jar").First();
// example: C:/Users/Venom/projects/New 2019 Unity Proj/New Unity Project/Assets
private static string ProjectPath => Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
public static string AndroidProjectPath => Path.Combine(ProjectPath, "Build");
private static string GetEditorPref(string key)
{
if (!EditorPrefs.HasKey(key))
{
throw new Exception($"Environment: {key} not set. Probably you can set it from Edit -> Preferences -> External Tools");
}
return EditorPrefs.GetString(key);
}
}
public static class ProcessRunner
{
public static int DoProcess(string workingDir, string fileName, string[] arguments)
{
return DoProcess(workingDir, fileName, string.Join(" ", arguments));
}
public static int DoProcess(string workingDir, string fileName, string arguments)
{
Debug.Log($"ProcessRunner: executing: {fileName} {arguments}\n\tWorking directory: {workingDir}");
int exitCode;
using (var process = new Process
{
StartInfo =
{
WorkingDirectory = workingDir,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
FileName = fileName,
Arguments = arguments,
RedirectStandardError = true,
RedirectStandardOutput = true
},
EnableRaisingEvents = true
})
{
using (var outputWaitHandle = new AutoResetEvent(false))
using (var errorWaitHandle = new AutoResetEvent(false))
{
process.OutputDataReceived += (sender, args) =>
{
// ReSharper disable once AccessToDisposedClosure
if (args.Data != null) Debug.Log(args.Data);
else outputWaitHandle.Set();
};
process.ErrorDataReceived += (sender, args) =>
{
// ReSharper disable once AccessToDisposedClosure
if (args.Data != null) Debug.LogError(args.Data);
else errorWaitHandle.Set();
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// process.WaitForExit causes hang when redirecting output e.g. with '> someFile.txt'
// So using wait handles instead
// https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why
WaitHandle.WaitAll(new WaitHandle[] { outputWaitHandle, errorWaitHandle });
exitCode = process.ExitCode;
Debug.Log($"ProcessRunner: process exit code {exitCode} in {(process.ExitTime - process.StartTime).TotalSeconds.ToString(CultureInfo.InvariantCulture)} sec ({fileName} {arguments})");
}
}
return exitCode;
}
}
public static class GradleHelper
{
public static void Run(string androidProjectPath, string task)
{
// example: -classpath "C:\Program Files\Unity\Hub\Editor\2019.3.2f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-5.1.1.jar" org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m" "assembleRelease"
var args = new[]
{
"-classpath", $"\"{Env.GradleExePath}\"",
"org.gradle.launcher.GradleMain",
"-Dorg.gradle.jvmargs=-Xmx4096m",
task
};
ProcessRunner.DoProcess(androidProjectPath, Env.JavaExePath, args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment