[Unity] ビルド後にApkをGoogle Driveにアップロードする

ゲームを実機で複数人で確認したいときにはGoogle Driveで共有している.
ただ、ビルドのたびにDriveにアップロードするのが面倒なので `PostProcessBuild`と[UnityGoogleDrive](https://github.com/Elringus/UnityGoogleDrive)を使用してアップロードを自動化する.

#環境
windows10
Unity 2018.2.18f
.Net 4.x 
# Google Drive APIの設定

設定の流れは[UnityGoogleDrive](https://github.com/Elringus/UnityGoogleDrive)のREADMEの通りにやればOK

* [release page](https://github.com/Elringus/UnityGoogleDrive/releases)から最新版をダウンロード & Unityにインポート

* `Edit/Project/Settings/Google Drive Settings`という項目ができているのでそれを開く
![2019-01-13 02_21_37-.png](https://qiita-image-store.s3.amazonaws.com/0/150338/de00f124-bc1d-9a07-b5b7-a94b97a6de05.png)

* Create Google Drive API Appを押す
![2019-01-13 02_21_59-ndk-bundle.png](https://qiita-image-store.s3.amazonaws.com/0/150338/73a86d2d-9a7a-029a-824b-97705209e9f1.png)

* Google Drive APIを登録するプロジェクトを選択(無い場合は作る)
(Google APIを設定したアカウントと保存するDriveのアカウントは違ってもいい)
![2019-01-13 03_15_04-API を有効にする - Google API コンソール.png](https://qiita-image-store.s3.amazonaws.com/0/150338/29d23092-65a2-3b51-e2f0-88b2203959c0.png)

***プロジェクト新しく作る場合***
![2019-01-13 02_23_32-新しいプロジェクト – Google API Console.png](https://qiita-image-store.s3.amazonaws.com/0/150338/9f6ed3fa-32b8-8ffc-2c85-c08dd27a5e99.png)

* `認証情報/認証情報を作成`からOAuth クライアントIDを作成
![2019-01-13 02_27_37-認証情報 - ApkDriveUploader - Google API コンソール.png](https://qiita-image-store.s3.amazonaws.com/0/150338/13f737ae-2d84-e876-062c-2e0d8cabee23.png)
***新しくプロジェクトを作成した***場合は***OAuth同意画面***を設定する必要あり

* OAuthクライアントをID作成

アプリケーションの種類は今回PCなのでその他,名前は適当に
![2019-01-13 02_27_56-OAuth クライアント ID の作成 - ApkDriveUploader - Google API コンソール.png](https://qiita-image-store.s3.amazonaws.com/0/150338/eef037cd-51ab-91c1-fc53-7e06797689c6.png)





* IDが完成したらOAuthのjsonをダウンロード(↓画像最右)
![2019-01-13 02_28_09-認証情報 - ApkDriveUploader - Google API コンソール.png](https://qiita-image-store.s3.amazonaws.com/0/150338/dcac5168-11a1-3e19-54f7-d6337efd18b0.png)


* Unity に戻り Google Drive Settingsに落としたjsonを読み込む
![2019-01-13 02_21_59__3.png](https://qiita-image-store.s3.amazonaws.com/0/150338/e8b5d1b7-1966-ab2a-dceb-1c94f2e65345.png)


これでGoogle Drive APIを使用する準備は完了.
あとはブラウザでOAuthの権限を承認すればOKなの**だが**,
Unityのビルド後に呼ばれる`PostProcessBuild`で動作する関数上でOAuth認証待ちをする(Coroutineを実行する)ができないっぽいので,一度認証用に`Play`してトークンを発行してからビルドするようにしてください.(~~単に自分がよくわかっていないので~~改善方があればおしえてくだしあ）

# 認証

`File/New Scene` でScene作成 以下コードを追加して実行する
![2019-01-13 03_42_53-EscapeRoomTemplate [C__Users_ookubo_Documents_UnityProjects_EscapeRoomTemplate] .png](https://qiita-image-store.s3.amazonaws.com/0/150338/71ca7fad-f989-3189-7c2f-44fb78931811.png)

[gist]
(https://gist.github.com/OhkuboSGMS/5d05f3abd5f959316e29ac408eec58d5)

```cs
using System.Collections;

    public class UploadTest : UnityEngine.MonoBehaviour
    {
        private void Start()
        {
            StartCoroutine(Upload());
        }

        IEnumerator Upload()
        {
            var data = new UnityGoogleDrive.Data.File
                {Name = "Test.txt", Content = System.Text.Encoding.UTF8.GetBytes("Hello Google Drive ")};
            var req = UnityGoogleDrive.GoogleDriveFiles.Create(data);
            print("Start Test Upload");
            yield return req.Send();
            print("Finish Test Upload");
        }
}
```

実行するとブラウザでOAuthの認証画面が出るのでDriveで保存するアカウント選んで認証する
![2019-01-13 02_31_41-ログイン - Google アカウント.png]
(https://qiita-image-store.s3.amazonaws.com/0/150338/522e265e-dd3f-1eb0-fb24-b481b4bbf0b4.png)

![2019-01-13 02_31_49-ログイン - Google アカウント.png](https://qiita-image-store.s3.amazonaws.com/0/150338/3129f35e-b793-64e9-6f6c-91990cc0928d.png)

認証終了後に Driveを確認して`Test.txt`がアップロードされていれば認証正しくできている

![2019-01-13 02_38_27-マイドライブ - Google ドライブ.png](https://qiita-image-store.s3.amazonaws.com/0/150338/40e7fe4d-2b7b-34bf-318d-a440e5023013.png)

#ビルド後にアップロード

認証が取れたのでビルド後にapkをアップロードできるようにします.
以下のコードを `Editor`フォルダ内に配置してください
[gist](https://gist.github.com/OhkuboSGMS/e41ac9a1a2159b14edce28bc83254eb4)

```cs

using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

public class UploadAPKAfterBuildFinish
{
    //このAttributeをつけた関数はBuild後に実行される
    [PostProcessBuild(100)]
    public static void OnAndroidBuildFinish(BuildTarget target, string pathToBuildProject)
    {
        if (target == BuildTarget.Android)
        {
            UploadApk(pathToBuildProject);
        }
    }

    static void UploadApk(string pathToBuildProject)
    {
        var apkName = pathToBuildProject.Split(new[] {'/'}).Last();// apkのファイル名を取得

        if (File.Exists(pathToBuildProject))
        {
            var apk = new UnityGoogleDrive.Data.File
                {Name = apkName, Content = File.ReadAllBytes(pathToBuildProject)};
            var req = UnityGoogleDrive.GoogleDriveFiles.Create(apk);
            req.OnDone += response =>
            {
                if (req.IsError) Debug.LogError(req.Error);
                if (req.IsDone)
                {
                    Debug.Log("Upload Success! See your Google Drive");
                    Debug.Log(response.WebViewLink);
                    if(!string.IsNullOrEmpty(response.WebViewLink))
                        Application.OpenURL(req.ResponseData.WebViewLink);
                }
            };
            
            req.Send();//upload

            
        }
        else
        {
            Debug.Log($"Built File Path:{pathToBuildProject} File Not Exists");
        }
    }
}
```

あとはビルドするだけ!
ビルド後に Driveに.apkがアップロードされている


参考記事

*  [[Unity] PostProcessでビルド後に処理を差し込む](https://qiita.com/edo_m18/items/346439f7678218e85e69)