Skip to content

Instantly share code, notes, and snippets.

@hmans
Last active August 30, 2025 04:36
Show Gist options
  • Select an option

  • Save hmans/ba85e337be18a6b3e98c667fbbdb402d to your computer and use it in GitHub Desktop.

Select an option

Save hmans/ba85e337be18a6b3e98c667fbbdb402d to your computer and use it in GitHub Desktop.

Revisions

  1. hmans revised this gist Mar 5, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion BobTheBuilder.cs
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@
    public class BobTheBuilder
    {
    /* List of scenes to include in the build */
    public static string[] scenes = { "Assets/HendrikMans/GAMENAME/Scenes/Game.unity" };
    public static string[] scenes = { "Assets/Scenes/Game.unity" };

    [MenuItem("GAMENAME/Build/All Targets")]
    public static void BuildAll()
  2. hmans revised this gist Mar 5, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions _readme.md
    Original file line number Diff line number Diff line change
    @@ -2,12 +2,12 @@

    Here's my "local build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method.

    > **Note** It
    > **Warning** Do not copy it verbatim and expect it to work. You **will** need to adapt it to your project, since it's making assumptions about export platforms, paths, and included scenes. Consider it a starting point for your own script!
    Running headless builds like this is a lot less work than switching platforms and triggering builds manually in the editor, and it is _most definitely_ faster than using the god-awfully slow Unity Cloud Build to do it. (In my game, running this local pipeline produces builds for all my targeted platforms in just over 7 minutes on my Macbook Pro, while Unity Cloud Build would often take longer than an hour.)

    As you can see from the code, it will read the secrets required for Play Store publishing from the environment. Ideally, in the future it will also source the Android build number like this (or maybe even increment it automatically.)

    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!

    – [@hmans](https://twitter.com/hmans), July 2020
    – [@hmans](https://twitter.com/hmans), July 2020 (updated March 2023)
  3. hmans revised this gist Mar 5, 2023. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions _readme.md
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,8 @@

    Here's my "local build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method.

    > **Note** It
    Running headless builds like this is a lot less work than switching platforms and triggering builds manually in the editor, and it is _most definitely_ faster than using the god-awfully slow Unity Cloud Build to do it. (In my game, running this local pipeline produces builds for all my targeted platforms in just over 7 minutes on my Macbook Pro, while Unity Cloud Build would often take longer than an hour.)

    As you can see from the code, it will read the secrets required for Play Store publishing from the environment. Ideally, in the future it will also source the Android build number like this (or maybe even increment it automatically.)
  4. hmans revised this gist Mar 5, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion build.sh
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ set -e
    -nographics \
    -silent-crashes \
    -logFile - \
    -projectPath $(pwd) \
    -projectPath "$(pwd)" \
    -quit \
    -executeMethod BobTheBuilder.BuildAll

  5. hmans revised this gist Jul 14, 2020. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions BobTheBuilder.cs
    Original file line number Diff line number Diff line change
    @@ -58,6 +58,9 @@ static void BuildAndroid()
    {
    Debug.Log("Starting Android Build!");

    /* We absolutely do not want to ever store secrets in code (or even add them to
    version control), so instead we'll fetch them from the system environment.
    Don't forget to set these environment variables before invoking the build script! */
    PlayerSettings.Android.keystorePass = Environment.GetEnvironmentVariable("KEY_STORE_PASS");
    PlayerSettings.Android.keyaliasPass = Environment.GetEnvironmentVariable("KEY_ALIAS_PASS");

  6. hmans revised this gist Jul 14, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion BobTheBuilder.cs
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    /* This needs to live in a folder named "Editor", or it won't work. */
    /* This needs to live in a folder named "Editor", or it won't work. Doesn't have to be named
    "BobTheBuilder", though. Name it whatever you want! */

    using System;
    using UnityEditor;
  7. hmans revised this gist Jul 14, 2020. No changes.
  8. hmans revised this gist Jul 14, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion _readme.md
    Original file line number Diff line number Diff line change
    @@ -8,4 +8,4 @@ As you can see from the code, it will read the secrets required for Play Store p

    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!

    – [@hmans](https://twitter.com/hmans)
    – [@hmans](https://twitter.com/hmans), July 2020
  9. hmans revised this gist Jul 14, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions _readme.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Local Unity Build Pipeline
    # Basic Local Unity Build Pipeline

    Here's my "local build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method.

    @@ -8,4 +8,4 @@ As you can see from the code, it will read the secrets required for Play Store p

    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!

    -- [@hmans](https://twitter.com/hmans)
    – [@hmans](https://twitter.com/hmans)
  10. hmans revised this gist Jul 14, 2020. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion _readme.md
    Original file line number Diff line number Diff line change
    @@ -6,4 +6,6 @@ Running headless builds like this is a lot less work than switching platforms an

    As you can see from the code, it will read the secrets required for Play Store publishing from the environment. Ideally, in the future it will also source the Android build number like this (or maybe even increment it automatically.)

    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!
    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!

    -- [@hmans](https://twitter.com/hmans)
  11. hmans revised this gist Jul 14, 2020. 3 changed files with 14 additions and 3 deletions.
    5 changes: 3 additions & 2 deletions BobTheBuilder.cs
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,13 @@
    /* This needs to live in a folder named "Editor". */
    /* This needs to live in a folder named "Editor", or it won't work. */

    using System;
    using UnityEditor;
    using UnityEngine;

    public class BobTheBuilder
    {
    public static string[] scenes = new[] { "Assets/HendrikMans/GAMENAME/Scenes/Game.unity" };
    /* List of scenes to include in the build */
    public static string[] scenes = { "Assets/HendrikMans/GAMENAME/Scenes/Game.unity" };

    [MenuItem("GAMENAME/Build/All Targets")]
    public static void BuildAll()
    10 changes: 9 additions & 1 deletion _readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,9 @@
    Here's my local "build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method. Running headless builds like this is a lot less work than switching platforms and triggering builds manually in the editor, and it is _most definitely_ faster than using the god-awfully slow Unity Cloud Build to do it. (In my game, running this local pipeline produces builds for all platforms in just over 7 minutes on my Macbook Pro, which takes Unity Cloud Build more than an hour.
    # Local Unity Build Pipeline

    Here's my "local build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method.

    Running headless builds like this is a lot less work than switching platforms and triggering builds manually in the editor, and it is _most definitely_ faster than using the god-awfully slow Unity Cloud Build to do it. (In my game, running this local pipeline produces builds for all my targeted platforms in just over 7 minutes on my Macbook Pro, while Unity Cloud Build would often take longer than an hour.)

    As you can see from the code, it will read the secrets required for Play Store publishing from the environment. Ideally, in the future it will also source the Android build number like this (or maybe even increment it automatically.)

    I'm a perpetual Unity newbie, so if you have any suggestions on how to tweak this further, let me know in the comments!
    2 changes: 2 additions & 0 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,8 @@
    #!/usr/bin/env sh
    set -e

    # Note I've hard-coded the path to the Unity executable. There's probably a million
    # ways to make this nicer.
    /Applications/Unity/Hub/Editor/2019.4.3f1/Unity.app/Contents/MacOS/Unity \
    -batchmode \
    -nographics \
  12. hmans created this gist Jul 14, 2020.
    79 changes: 79 additions & 0 deletions BobTheBuilder.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    /* This needs to live in a folder named "Editor". */

    using System;
    using UnityEditor;
    using UnityEngine;

    public class BobTheBuilder
    {
    public static string[] scenes = new[] { "Assets/HendrikMans/GAMENAME/Scenes/Game.unity" };

    [MenuItem("GAMENAME/Build/All Targets")]
    public static void BuildAll()
    {
    BuildHTML5();
    BuildWindows();
    BuildMacOS();
    BuildiOS();
    BuildAndroid();
    }

    [MenuItem("GAMENAME/Build/HTML5 (release)")]
    public static void BuildHTML5()
    {
    Debug.Log("Starting HTML5 Build!");
    BuildPipeline.BuildPlayer(
    scenes,
    "Build/HTML5",
    BuildTarget.WebGL,
    BuildOptions.None);
    }

    [MenuItem("GAMENAME/Build/Windows (release)")]
    public static void BuildWindows()
    {
    Debug.Log("Starting Windows Build!");
    BuildPipeline.BuildPlayer(
    scenes,
    "Build/Windows/GAMENAME.exe",
    BuildTarget.StandaloneWindows,
    BuildOptions.None);
    }

    [MenuItem("GAMENAME/Build/macOS (release)")]
    public static void BuildMacOS()
    {
    Debug.Log("Starting macOS Build!");
    BuildPipeline.BuildPlayer(
    scenes,
    "Build/macOS/GAMENAME.app",
    BuildTarget.StandaloneOSX,
    BuildOptions.None);
    }

    [MenuItem("GAMENAME/Build/Android (release)")]
    static void BuildAndroid()
    {
    Debug.Log("Starting Android Build!");

    PlayerSettings.Android.keystorePass = Environment.GetEnvironmentVariable("KEY_STORE_PASS");
    PlayerSettings.Android.keyaliasPass = Environment.GetEnvironmentVariable("KEY_ALIAS_PASS");

    BuildPipeline.BuildPlayer(
    scenes,
    "Build/Android/GAMENAME.aab",
    BuildTarget.Android,
    BuildOptions.None);
    }

    [MenuItem("GAMENAME/Build/iOS (release)")]
    static void BuildiOS()
    {
    Debug.Log("Starting iOS Build!");
    BuildPipeline.BuildPlayer(
    scenes,
    "Build/iOS",
    BuildTarget.iOS,
    BuildOptions.AcceptExternalModificationsToPlayer);
    }
    }
    1 change: 1 addition & 0 deletions _readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Here's my local "build pipeline" for Unity. It consists of a C# Editor script defining the various build targets and a convenient `BuildAll` method, and a shell script that invokes the latter method. Running headless builds like this is a lot less work than switching platforms and triggering builds manually in the editor, and it is _most definitely_ faster than using the god-awfully slow Unity Cloud Build to do it. (In my game, running this local pipeline produces builds for all platforms in just over 7 minutes on my Macbook Pro, which takes Unity Cloud Build more than an hour.
    13 changes: 13 additions & 0 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    #!/usr/bin/env sh
    set -e

    /Applications/Unity/Hub/Editor/2019.4.3f1/Unity.app/Contents/MacOS/Unity \
    -batchmode \
    -nographics \
    -silent-crashes \
    -logFile - \
    -projectPath $(pwd) \
    -quit \
    -executeMethod BobTheBuilder.BuildAll

    echo "Done!"