Unity3Dである程度自動ビルドする

> 本記事の内容を[はてなブログ](https://nanmo.hateblo.jp/entry/2014/11/18/000000)に転記しました。
> すぐにQiitaの記事を削除する予定はありませんが、どちらか一方だけ残すとなったらはてなブログの方を残すと思います。
> ご承知おき下さい。

「Unity3Dで自動ビルド？　ああ簡単だよ！ :smile: 」という割にはいざやってみようとするとめんどくさいでお馴染み(当人調べ)のUnity3Dの自動ビルドの話です。

検索してみると大体必要な情報は引っかかるんですが、何故かシーンのstring[]指定をハードコーディングしなきゃいけないような記述ばっかり見つかるので、そんなんBuild SettingsのScenesから引っ張ったらええやんけ！　ということで書いておきます。

なお、

* エディタ上から実行することを想定しています(コマンドラインからのバッチモードでの動作検証はしていません)
* Player SettingsやBuild Settingsが予めきちんと設定されていることを想定しています(全部のオプションが触れるわけではないようなので、スクリプトから変更していません)。
* ビルド先のパス指定はプラットフォームによってフォルダ指定だったり、ファイルそのもの(拡張子含む)の指定だったり、予めフォルダを作っておいてあげないといけなかったりと色々です。
* よくわかりませんが、 [EditorBuildSettings.scenes](http://docs.unity3d.com/412/Documentation/ScriptReference/EditorBuildSettings-scenes.html) は最新のドキュメントから省かれています(実行自体は問題ない)。非推奨になったのかもしれませんが使えなくなると影響大きすぎる気がします。

シンプルにしたかったんですが、色々と処理が必要だったので関数ちらほら作ってます。
以下はWindows32のビルドしか書いてませんがもちろん色々と増やしたり出来ます、適当に弄って増やして下さい。

```cs
using UnityEngine;
using UnityEditor;
using System;

// Assets/Editorに保存する
public class AutoBuild : MonoBehaviour {

	static BuildTarget workingTarget;
	
	[MenuItem ("Build/Win32Player")]
	static void Windows32Build() {
		SaveWorkingTarget();
		Building( BuildTarget.StandaloneWindows, BuildOptions.None, "Win32/Standalone.exe" );
		//実行ファイル名を指定、この指定だとプロジェクトフォルダ/Win32/Standalone.exeと出力される
		RestoreWorkingTarget();
	}

	static string[] GetAllScenePaths() {
		string[] scenes = new string[EditorBuildSettings.scenes.Length];
		
		for( int i = 0; i < EditorBuildSettings.scenes.Length ; i++ ) {
			scenes[i] = EditorBuildSettings.scenes[i].path;
		}

		return scenes;
	}

	static void Building( BuildTarget target, BuildOptions options, string buildPath) {
		string targetName = Enum.GetName(target.GetType(), target);
		string message = "";
		Debug.Log("Begin Build Player:" + targetName );
		if ( EditorUserBuildSettings.activeBuildTarget != target ) {
			EditorUserBuildSettings.SwitchActiveBuildTarget( target );
		}
		message = BuildPipeline.BuildPlayer( GetAllScenePaths(), buildPath, target, options );
		Debug.Log("End Build Player:" + targetName );
		if ( message != "" ) {
			Debug.LogWarning(message);
		}
	}

	static void Building( BuildTarget target, BuildOptions options) {
		Building( target, options, Enum.GetName(target.GetType(), target) );
	}

	static void SaveWorkingTarget() {
		workingTarget = EditorUserBuildSettings.activeBuildTarget;
	}

	static void RestoreWorkingTarget() {
		if ( workingTarget != EditorUserBuildSettings.activeBuildTarget ) {
			Debug.Log ("Restore Working Target:" + Enum.GetName( workingTarget.GetType(), workingTarget ) );
			EditorUserBuildSettings.SwitchActiveBuildTarget(workingTarget);
		}
	}
}
```

以下、参考

* [Unity - Manual: Build Player Pipeline](http://docs.unity3d.com/Manual/BuildPlayerPipeline.html)
* [Unity - Scripting API: BuildPipeline.BuildPlayer](http://docs.unity3d.com/ScriptReference/BuildPipeline.BuildPlayer.html)
* [Unity - Scripting API: BuildTarget](http://docs.unity3d.com/ScriptReference/BuildTarget.html)
* [Unity - Scripting API: EditorUserBuildSettings.SwitchActiveBuildTarget](http://docs.unity3d.com/ScriptReference/EditorUserBuildSettings.SwitchActiveBuildTarget.html)
* [Unity - Scripting API: MenuItem](http://docs.unity3d.com/ScriptReference/MenuItem.html)
* [Unity - Scripting API: BuildOptions](http://docs.unity3d.com/ScriptReference/BuildOptions.html)
* [Unity Script Reference – EditorBuildSettings.scenes](http://docs.unity3d.com/412/Documentation/ScriptReference/EditorBuildSettings-scenes.html)