Unityプロジェクトをコマンド1発でiOS実機にデプロイ＆起動する

# モチベーション
UnityのiOS向けデバッグビルドと実機デプロイが遅くて待ってられない。
しかもUnity上でRunしてもXcodeプロジェクトが吐き出されるだけなので、
1. Unity上でRun
2. 吐き出されたXcodeプロジェクトをXcode上でRun
と2回Runボタンを押さないと実機にデプロイできない。めんどくさい。トイレ行けない。

コマンド1回叩いたらトイレに行っててもiOS実機にデプロイできるようにしたい。


# 手順
##1 動作要件
- (iOSなので)Mac OS Xが入っているマシン
- ios-deploy (https://github.com/phonegap/ios-deploy)
  - ``brew install ios-deploy``で入る。
- XcodeとかUnityとか

##2 バッチ実行の準備
Assetsディレクトリの直下に``Editor``ディレクトリを作成し、以下のBatchBuild.csを作成する。
名前が重要なので、"Editor"のスペルとキャピタライズに注意。

*Android等向けのコードも入っていますが今回は使いません*

```BatchBuild.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class BatchBuild : MonoBehaviour {

    static private string ApplicationName = "Hoge-application";
	//for Android
	static void BuildProject_Android(){

		Debug.Log ("AndroidBuild...");


		string[]		scenePaths	= GetEnabledScenePaths();
		string			outputPath	= Application.dataPath + "/../"+ApplicationName+".apk";
		BuildTarget		target		= BuildTarget.Android;
		BuildOptions	opt			= BuildOptions.None;

		ApplicationBuild(scenePaths,outputPath,target,opt);
	}

	//for iOS Device
	static void BuildProject_iOS(){

		Debug.Log ("iOSBuild...");

		string[]		scenePaths	= GetEnabledScenePaths();
		string			outputPath	= "Device";
		BuildTarget		target		= BuildTarget.iOS;
		BuildOptions	opt			= BuildOptions.SymlinkLibraries;

		//ProjectDataSize Reduction
		EditorUserBuildSettings.symlinkLibraries = true;
		//Prevent SimulatorBuild
		PlayerSettings.iOS.sdkVersion = iOSSdkVersion.DeviceSDK;

		ApplicationBuild(scenePaths,outputPath,target,opt);
	}

	//RunBuild
	static void ApplicationBuild(string[] scenePaths,string outputPath,BuildTarget target,BuildOptions opt){

		string error = BuildPipeline.BuildPlayer(scenePaths,outputPath,target,opt);

		if (!string.IsNullOrEmpty(error))
			Debug.LogError(error);		//BuildFailed
		EditorApplication.Exit(string.IsNullOrEmpty(error) ? 0 : 1);

	}

	//return Enabled Scene in BuildSettings's Scenes In Build 
	static string[] GetEnabledScenePaths() {

		List<string> sceneList = new List<string>();

		//Check Scenes Enabled
		foreach(var scene in EditorBuildSettings.scenes){
			if(scene.enabled)
				sceneList.Add (scene.path);
		}
		return sceneList.ToArray();
	}

}
```

##3 コマンドの実行

**空のディレクトリ**を用意し、以下のシェルスクリプトを配置、実行する。
Unityのビルド、Xcodeのビルドが走ったのち、iOS実機上でUnityアプリが起動したら成功
*$BASH_SOURCEを利用しているためbash or zsh系でしか動かない気がします*

```deploy_to_ios.sh
#Locate this script under an empty directory.

PROJECT_BUILD_DIR=`pwd`/`dirname $BASH_SOURCE` # <= Must be absolute path
PROJECT_BASE=/path/to/unity-project-base-directory # <= Edit this
APP_NAME=Hoge-application.app # <= Edit this

cd $PROJECT_BUILD_DIR

echo "Copying sources"
rm -r Assets 2>/dev/null
rm -r ProjectSettings 2>/dev/null
cp -r $PROJECT_BASE/Assets/ Assets/
cp -r $PROJECT_BASE/ProjectSettings/ ProjectSettings/

echo "Building Unity"
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath $PROJECT_BUILD_DIR -executeMethod BatchBuild.BuildProject_iOS -quit
if [ $? != 0 ]; then
  echo "Unity Build failed"
  exit $?
fi

echo "Building Xcode Project"
xcodebuild -project $PROJECT_BUILD_DIR/Device/Unity-iPhone.xcodeproj -target Unity-iPhone -configuration Release build
if [ $? != 0 ]; then
  echo "Xcode Build failed"
  exit $?
fi

echo "Deploying to the device"
ios-deploy --debug --bundle $PROJECT_BUILD_DIR/Device/build/Release-iphoneos/$APP_NAME
if [ $? -eq 254 ]; then
  echo "Deploying finished, but couldn't run app"
  exit $?
elif [ $? -ne 0 ]; then
  echo "Deploying failed"
  exit $?
fi
```

##4 備考
Unityビルドするときに、``Assets``フォルダと``ProjectSettings``フォルダをまるまるコピーしているところが重要です。
Unity開発環境を開いたまま、``Assets``や``ProjectSettings``をコピーせずにビルドしようとすると、
> It looks like another Unity instance is running with this project open.

などと言われうまく実行できません。

また、シンボリックリンク等では、Unityに
> Assets is a symbolic link. Using symlinks in Unity projects may cause your project to become corrupted if you create multiple references to the same asset, use recursive symlinks or use symlinks to share assets between projects used with different versions of Unity. Make sure you know what you are doing.

などと怒られて同じくうまく実行できません。
諦めて別のディレクトリにまるまるコピーしてきましょう。

iOS実機にパスコードがかかっている場合はデプロイはできるものの起動はしてくれません。諦めて自分で起動しましょう。

*本当はMakefile書きたかったけどめんどくさくてやめた*

#出典
Unityのバッチファイルの作成については[ここ](http://yutakaseda3216.hatenablog.com/entry/2015/12/07/221714)を参考にしました。参考というより丸パクリです。

Xcodeのビルドについては[このへん](http://blog.ch3cooh.jp/entry/20150210/1423573065)を参考にしました。