🐈

[Unity]GoogleDrive上の指定のフォルダ内のファイルをダウンロードする

2021/11/12に公開

Unityから指定のメニューを選択すると、Google Driveの特定のフォルダ内に格納されたファイルを全部ダウンロードしてくるメモです。

  • Windows 10
  • Unity 2020.1.6f1
  • UnityGoogleDrive 0.27.0

UnityGoogleDriveの導入

UnityからGoogleDriveを操作するにあたって、以下のライブラリを導入します。

https://github.com/Elringus/UnityGoogleDrive

上記のライブラリはUPMに対応しているため、以下の手順で導入できます。

  • UnityのメニューからWindow - Package Manager を選択
  • ボタンからAdd package from git URL...を選択
  • https://github.com/Elringus/UnityGoogleDrive.git#packageと入力し、Addボタンを押下

Google Drive APIの利用準備

API経由でGoogle Driveにアクセスするため、Google Drive APIの設定を行います。

  • Unity Editorのメニューから、Edit - Project Settingsを選択

  • Google Driveを選択

  • Create Google Drive API appを選択すると、ブラウザでGoogle Cloud Platformが開く
    ※Google Cloud Platformに登録していない場合、登録の作業が必要になります。

プロジェクトの作成

既存のプロジェクトが存在しない場合は、以下の画面が開きます。

  • プロジェクトを新規作成

APIへのアクセスの有効化

プロジェクトの新規作成後、または既にプロジェクトが存在している場合、APIへのアクセスの有効化のページが開きます。ここで、Google Drive APIを有効にします。

  • 次へを選択

  • 有効にするを選択

OAuth同意画面の設定

次に、OAuth同意画面の設定を行います。

  • メニュー - APIとサービス - OAuth同意画面を選択

  • 外部を選択して作成ボタンを押下

  • アプリ情報アプリ名ユーザーサポートメールを入力

  • デベロッパーの連絡先情報メールアドレスを入力

  • 保存して次へ

  • スコープを追加または削除を選択

  • Google Drive API.../auth/drive.readonlyを追加

  • 更新ボタンを選択

機密性の高いスコープにGoogle Drive APIが追加されます。

  • 保存して次へを選択

  • ADD USERSを選択、テストユーザーを追加

  • Google Driveにアクセスするアカウントのメールアドレスを登録

  • 保存して次へを選択

  • 一通り設定を確認して、ダッシュボードに戻るを選択

認証情報の設定

次に、認証情報の設定を行います。

  • APIとサービス - 認証情報 を開く

  • 認証情報を作成 - OAuthクライアントIDを選択

  • アプリケーションの種類名前を設定

  • 作成ボタンを押下

  • JSONをダウンロードを選択してJSONファイルを保存しておく

UnityでJSONを読み込み

Unity Editorに戻って、Google Driveへの接続の設定を行います。

  • Project Settings - Google Driveを開く
  • Parse generic credentials JSON file...を選択
  • ファイル選択ダイアログが開くので、先ほど保存したJSONファイルを選択します。
    Client_id等の設定が読み込まれれば完了です。

Unity側のスクリプトの作成

Unityのメニューから処理を実行する

Editorフォルダを作成し、その中にダウンロード処理を記載するスクリプトを新規作成します。
UnityGoogleDriveを使用するため、using UnityGoogleDriveを追加しておきます。
staticメソッドにMenuItemアトリビュートを付けると、Unityのメニューから呼び出せるようになります。

using UnityEngine;
using UnityEditor;
using UnityGoogleDrive;

public static class GoogleDriveDownloader
{
	[MenuItem("Tools/DownloadFromGoogleDrive")]
	private static void DownloadFromGoogleDrive()
	{
		Debug.Log(nameof(DownloadFromGoogleDrive));
	}
}

指定フォルダ内のファイルの一覧を取得する

任意のフォルダ内に含まれるファイルの一覧を取得してみます。

まず、GoogleDriveでフォルダのIDを取得します。
任意のフォルダに移動すると以下のようなURLが表示されます。
このURLのXXXXXXXXXXXXXXXXXXXXXXXの部分が、フォルダのIDになります。
https://drive.google.com/drive/u/0/folders/XXXXXXXXXXXXXXXXXXXXXXX

次に、スクリプトを記載します。
ファイルの一覧を取得するには、GoogleDriveFiles.List()を使用します。

private const string folderId = "XXXXXXXXXXXXXXXXXXXXXXXXXX";

private static void ListFiles()
{
	var request = GoogleDriveFiles.List();
	// 取得するフィールドを設定
	 request.Fields = new List<string> { "files(id, name, size, createdTime)" };
	 // クエリの内容を設定
	 request.Q = $"\'{folderId}\' in parents";
	 request.Send().OnDone += OnListReceived;
}

private static void OnListReceived(UnityGoogleDrive.Data.FileList list)
{
	// フォルダをリストアップ
	foreach(var file in list.Files)
	{
		Debug.Log($"ID:{file.Id}, Name:{file.Name}");
	}
}

Fieldsの記載方法

request.Fields = new List<string> { "files(id, name, size, createdTime)" };

request.Fieldsに取得するフィールドを記載します。
ここの記述方法は、Google Drive APIのFieldsの記述方法に準拠します。
https://developers.google.com/drive/api/v3/fields-parameter
ファイルのメタデータに関しては以下のページに記載があります。
https://developers.google.com/drive/api/v3/reference/files

今回の場合は、ファイルのID、名前、サイズ、作成日を取得しています。

Qの記載方法

request.Q = $"\'{folderId}\' in parents";

request.Qには、ファイルを検索する際のクエリの内容を記載します。
こちらについては、Google Drive APIの以下のページが参考になります。
https://developers.google.com/drive/api/v3/search-files
使用できるOperetorとQuery termは以下のページにまとまっています。
https://developers.google.com/drive/api/v3/ref-search-terms

今回の場合は、指定したフォルダIDの親を持つファイルを検索しています。

ファイルのダウンロード

任意のID、ファイル名のファイルをダウンロードします。
ファイルをダウンロードするには、GoogleDriveFiles.Downloadを使用します。

using System.IO;

// ~~ 中略 ~~

private static void DownloadFile(string fileId, string fileName)
{
	var path = Path.Combine(Application.dataPath, fileName).Relace("\\", "/");
	var request = GoogleDriveFiles.Download(fileId: fileId);
	request.Send().OnDone() += (file) =>
	{
		File.WriteAllBytes(path, file.Content.byteData);
		AssetDatabase.Refresh();
	};
}

その他

リストの取得やダウンロードで使用するrequest.Send()はawaitに対応しているので、async/awaitで記載するとすっきりするケースもあると思います。その場合は、request.ResponseDataによって取得したFileListFileにアクセスできます。

Discussion