Unityのプロジェクトをスクリプトからビルドするには、Unityのエディタで動かすスクリプトからBuildPipeline.BuildPlayer()を呼び出してやればよい。でそれをコマンドラインから呼び出せばok。

簡単な例

エディタ用のスクリプトファイルを追加して(ex. Assets/Editor/BuildBatch.cs)、例えばAndroid用にビルドするには、

// Assets/Editor/BuildBatch.cs
using UnityEngine;
using UnityEditor;
using System;

public class BuildBatch : MonoBehaviour {
  private static void BuildAndroid() {
    string [] scenePaths = {
      "Assets/TestScene.unity"
    };
    string outputPath = Application.dataPath + "/../out.apk";  // dataPathはAssetを指している
    BuildTarget target = BuildTarget.Android;
    BuildOptions opt = BuildOptions.SymlinkLibraries;
    string error = BuildPipeline.BuildPlayer(scenePaths, outputPath, target, opt);
    if (!string.IsNullOrEmpty(error))
      Debug.LogError(error);
    EditorApplication.Exit(string.IsNullOrEmpty(error) ? 0 : 1);
  }
}

などというメソッドを用意してやって、これを外部から呼び出してやる。

コマンドラインからUnityスクリプトのメソッドを呼び出す

Unityのバッチモードというのを使って、コマンドラインから呼び出す:

# build.sh
$ Unity -batchmode -projectPath <ユニティのプロジェクトのパス> -buildTarget android -executeMethod BuildBatch.BuildAndroid -quit
  • MacOSXの場合、Unityの実行ファイルのパスは /Applications/Unity/Unity.app/Contents/MacOS/Unity
  • -batchmode でバッチモード指定
  • -executeMethod で実行するメソッドを指定(クラス.メソッドの形)
  • -quitでメソッドが終わったらエディタを終了させる

出力するシーンの列挙

BuildPipeline.BuildPlayer() の第一引数には出力するシーンのパスの配列を与えるが、いちいちシーンを追加するのはかったるいので、ビルドセッティングから取得する:

using System.Linq;

  private static string[] GetAllScenePaths() {
    return EditorBuildSettings.scenes.Select(scene => scene.path).ToArray();
  }

Android

キーストアの指定をする

Android用にビルドして作成するapkに署名するにはキーストアのパスワードが必要になる。なぜかUnityの設定が保存されないので、バッチビルド時に指定してやる:

// Assets/Editor/BuildBatch.cs
    PlayerSettings.Android.keystorePass = キーストアのパスワード;
    PlayerSettings.Android.keyaliasName = エイリアス名;
    PlayerSettings.Android.keyaliasPass = エイリアスパスワード;

iOS

ターゲットがiOSの場合、.ipaなどが直接出力されるわけじゃなくて、Xcodeのプロジェクトが出力される。

プロジェクトの設定などを修正する必要がある場合、C#からXcodeのプロジェクトを扱えるXCodeEditor-for-Unityなどを使うとよい。

Xcodeのプロジェクトをコマンドラインからビルドするには、shenzhenを使うと楽であった。

番外編:メニューから呼び出す

コマンドラインからビルドするにはUnityをいったん閉じないといけないが、ビルドのスクリプトを作成/修正している段階だと閉じたり開いたりするのが大変である。そこでメニューから実行できるようにして動作の確認をすると楽である:

// Assets/Editor/BuildBatch.cs
public class BuildBatch : MonoBehaviour {
  // メニューに追加するメソッド
  [MenuItem ("Build/Android")]
  static void BuildAndroidMenuItem() {
    DoBuildAndroid();
  }

  // コマンドラインから呼び出すメソッド
  private static void BuildAndroid() {
    bool result = DoBuildAndroid();
    EditorApplication.Exit(result ? 0 : 1);
  }

  // 実際にビルドするメソッド:成功/失敗を返す
  private static bool DoBuildAndroid() {
    ...
    return string.IsNullOrEmpty(error);
  }

ビルドするメソッドから成功/失敗を返すようにして、コマンドラインから呼びだされた場合にだけEditorApplication.Exit()で終了させてやる。