【Mac】UnityからGoogleDrive内のファイルをインポートする方法を超丁寧に解説する

GoogleDrive内に置いてあるマスターデータJsonファイルをUnityにインポートしたい。

手動でGoogleDriveからダウンロードしてUnityエディタに入れても良いんだけど、更新するたびに手動でやるのは面倒なので、できれば自動化したい。

ということで、やってみました。

元々の意図はJsonファイルのインポートですが、この記事ではJsonファイルに限りません。

タイトル通り、MacでUnityからGoogleDrive内のファイルをインポートする方法を、超丁寧に解説します。

GoogleApisをダウンロードする

まずはGoogleApisのDLLファイルをダウンロードします。

Windowsなら簡単にできそうなのですが、MacでGoogleApisをダウンロードする場合は一手間必要です。

(ここの上手い方法が分からなかったので、もしもっと簡単な方法があったら教えて欲しいです)

まず、Visual Studio for Macが入っていない場合は、こちらからインストールしてください。

Visual Studio Code(VSCode)は別物なので注意。

GoogleApisはVisualStudioを通してダウンロードします。

VisualStudioをインストールできたら、起動して「ファイル」 > 「新しいソリューション」から新規プロジェクトを作成します。

「Web and Console」の「アプリ」を選択し、「コンソール アプリケーション」を選択した上で次へ。

対象のフレームワークはデフォルトのままで次へ。

プロジェクト名と保存先を適当に入力。プロジェクト名と同じ文字列が自動でソリューション名にも入力されます。

その他はデフォルトのままにして、作成を選択。

エディタが開かれるので、左のソリューションパネルの中にある「依存関係」を右クリック。

その中にある「NuGetパッケージの管理…」を選択。

「NuGetパッケージの管理 – InstallGoogleApi」というウィンドウが開かれるので、左上のプルダウンが「nuget.org」になっていることを確認した上で、以下のパッケージを追加します。

  • Google.Apis
  • Google.Apis.Auth
  • Google.Apis.Core
  • Google.Apis.Drive.v3
  • Google.Apis.Script.v1
  • Google.Apis.Sheets.v4
  • Newtonsoft.json

右上に検索窓があるので、検索して見つけてください。

上記リストの項目全てにチェックを入れ、「パッケージの追加」で追加できます。

パッケージの追加には数秒かかりますが、ダウンロードが終わるとソリューションパネルの「依存関係」の子要素に先ほどのパッケージが入っているのが分かります。

対象パッケージのダウンロードが終わったら、左上にある実行ボタン(再生ボタン)を押して、一度実行します。

デフォルトで記述されている「Hello, World!」をコンソールに表示するだけのプログラムが実行されますが、これによってフォルダ内にDLLファイルが生成されます。

生成されたものをFinderで確認しましょう。

「依存関係」の親要素を右クリックし、「Finderで表示」をクリック。

すると、こんな感じで bin/Debug/netcoreapp3.1 内にいくつかファイルが生成されているのが分かります。

最後に、生成されたファイルのうち先ほどのリストにあるDLLファイルをUnityエディタにドラッグ&ドロップします。

今回はPlugins/GoogleApisというフォルダを作ってその中に入れました。

場所は好きなところで大丈夫です。

Google Cloud Platformを設定する

次に、Google Cloud Platformの設定をします。

Google Cloud Platformのページに移動し、GoogleDriveにアクセスした時と同じGoogleアカウントでログインします。

「Google Cloud Platform」の右にある「プロジェクトの選択」をクリック。
(一度も利用したことがない方はもしかしたら文言が違うかも?)

「プロジェクトの選択」モーダルが開かれるので、右上の「新しいプロジェクト」をクリック。

プロジェクト名を適当に入力します。

場所は「組織なし」でOK。

「作成」をクリックします。

規約の同意が求められる場合は問題なければ同意し、左のメニューから「APIとサービス」を選択。

「OAuth同意画面」をクリックし、「外部」を選んで「作成」。

アプリケーション名を適当に入力し、「保存」をクリック。

ちなみにアプリケーション名に「Google」という文字列が入っているとエラーになるため、「Google」などの文字列を含まないアプリケーション名にする必要があるようです。

次に、「認証情報」から「認証情報を作成」をクリックし、「OAuthクライアントID」をクリック。

アプリケーションの種類は「デスクトップアプリ」を選択し、適当にアプリケーション名を入力したら「作成」。

「OAuth クライアントを作成しました」というモーダルが表示されたら閉じます。

「OAuth 2.0 クライアントID」の右端にあるダウンロードアイコンをクリックし、ダウンロードされた設定jsonファイルをUnityエディタ内に入れておきます。

再びGoogle Cloud Platformに戻り「ダッシュボード」を選択、そして上部にある「APIを有効化」をクリック。

APIライブラリのページに行くので、Google Drive APIを選択し、「有効にする」をクリック。

これでGoogle Cloud Platformでの設定は終わりました。

Unityでの実装

長い道のりでしたが、ついにUnityでの実装に入ります。

まず、以下の3ファイルをUnityエディタ内のEditorフォルダ直下に作成します。

FileImporter.cs


using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
/// <summary>
/// GoogleDriveからファイルをインポート
/// </summary>
public static class FileImporter
{
/// <summary>
/// インポート先
/// </summary>
private static string DESTINATION_PATH = "./Assets/destination/path.json";
/// <summary>
/// GoogleDriveにある対象のファイルID
/// </summary>
private static string DRIVE_FILE_ID = "YOUR_DRIVE_FILE_ID";
/// <summary>
/// インポートしたい時に呼び出す
/// </summary>
[MenuItem("Tools/GoogleDriveからインポート")]
private static async void Import()
{
ImportProgress.Init();
var context = SynchronizationContext.Current;
await Task.Run(() =>
{
ImportProgress.UpdateStatus(ImportProgress.ProgressStatus.Downloading);
context.Post(_ =>
{
GoogleDriveImporter.Import(DRIVE_FILE_ID, DESTINATION_PATH,
() => ImportProgress.UpdateStatus(ImportProgress.ProgressStatus.Finished));
}, null);
});
}
}

GoogleDriveImporter.cs


using System;
using UnityEditor;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Download;
using Google.Apis.Util.Store;
using System.IO;
using System.Threading;
/// <summary>
/// GoogleDriveからファイルをインポート
/// </summary>
public static class GoogleDriveImporter
{
/// <summary>
/// GoogleDriveAPIの設定ファイル
/// </summary>
private static string CLIENT_SECRET_FILE = "./Assets/client/secret/path/client_secret.json";
/// <summary>
/// GoogleDriveAPIの出力ファイル
/// </summary>
private static string CREDENTIAL_FILE = "./Assets/credential/path/credential.json";
/// <summary>
/// GoogleDriveからインポート
/// </summary>
public static void Import(string fileID, string destPath, Action onComplete)
{
// スコープを設定
string[] scopes = { DriveService.Scope.DriveReadonly };
// 認証
UserCredential credential;
using (var stream = new FileStream(CLIENT_SECRET_FILE, FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
"user",
CancellationToken.None,
new FileDataStore(CREDENTIAL_FILE, true)).Result;
}
// GoogleDriveAPIに必要
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "default name",
});
// ファイル取得
var request = service.Files.Get(fileID);
var output = new FileStream(destPath, FileMode.Create, FileAccess.Write);
request.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Completed:
{
// 成功
ImportProgress.UpdateStatus(ImportProgress.ProgressStatus.Converting);
ImportProgress.Post(() =>
{
AssetDatabase.ImportAsset(destPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
output.Close();
onComplete?.Invoke();
});
break;
}
case DownloadStatus.Failed:
{
// 失敗
UnityEngine.Debug.LogError("インポートに失敗しました: " + progress.Exception);
ImportProgress.UpdateStatus(ImportProgress.ProgressStatus.Error);
break;
}
}
};
request.Download(output);
}
}

ImportProgress.cs


using System.Threading;
using UnityEditor;
using UnityEngine.Events;
/// <summary>
/// インポートの進度を表示
/// </summary>
public static class ImportProgress
{
/// <summary>
/// 進度
/// </summary>
public enum ProgressStatus
{
Preparing,
Downloading,
Converting,
Finished,
Error,
}
/// <summary>
/// SynchronizationContext
/// </summary>
private static SynchronizationContext context;
/// <summary>
/// 初期化
/// </summary>
public static void Init()
{
context = SynchronizationContext.Current;
UpdateStatus(ProgressStatus.Preparing);
}
public static void Post(UnityAction action)
{
context.Post(_ => action?.Invoke(), null);
}
/// <summary>
/// 進度を更新
/// </summary>
public static void UpdateStatus(ProgressStatus status)
{
context.Post(_ =>
{
switch (status)
{
case ProgressStatus.Preparing:
EditorUtility.DisplayProgressBar("インポート中", "ファイル作成中...", 0.1f);
break;
case ProgressStatus.Downloading:
EditorUtility.DisplayProgressBar("インポート中", "ファイルダウンロード中...", 0.4f);
break;
case ProgressStatus.Converting:
EditorUtility.DisplayProgressBar("インポート中", "ファイル展開中...", 0.8f);
break;
case ProgressStatus.Finished:
case ProgressStatus.Error:
EditorUtility.ClearProgressBar();
break;
}
}, null);
}
}

FileImporter.csのDESTINATION_PATHには、インポート先のフォルダパスを指定してください。

同じくFileImporter.csのDRIVE_FILE_IDには、インポートするGoogleDrive内のファイルIDを指定します。

ファイルIDはGoogleDriveの対象ファイルを右クリックして「共有」を選択し、
コピーしたリンク「https://drive.google.com/file/d/XXXXXXXXXXXXX/view?usp=sharing」の「XXXXXXXXXXXXX」部分です。

GoogleDriveImporter.csのCLIENT_SECRET_FILEには、先ほどダウンロードした設定jsonファイルのパスを指定します。

そのままだとファイル名が長いので、client_secret.jsonという名前にリネームしました。

同じくGoogleDriveImporter.csのCREDENTIAL_FILEはGoogleDriveAPIの処理をした時に出力される(特に気にしなくて良い)ファイルのパスです。

パスはどこでも良いので、CLIENT_SECRET_FILEと同じフォルダとかにしておきましょう。

エディタでインポートを実行する

ようやくインポート処理を実行します。

Unityエディタのメニューバーから Tools > GoogleDriveからインポート を選択します。

プログレスバーが表示された直後、初回実行時はブラウザが開いて認証を求められます。

先ほどから使っているGoogleアカウントでログインし、いろいろ許可していきます。

もし上の画像のように警告が出た場合は、左下の「詳細」をクリックして詳細を開き、「FileImporter(安全ではないページ)に移動」をクリック。

もとのページに戻るので、出てきたダイアログで「許可」を選択。

Received verification code. You may now close this window.

というメッセージが表示されたら認証は完了なので、タブを閉じてUnityエディタに戻ります。

すると、指定したパスにダウンロードされたファイルが出力されているはずです。

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です