【Unity】AssetBundleをFirebaseで使ってみる

使わなくて良いなら、一生使いたくない。そう思っていました。。

 

 

AssetBundleとは

公式サイトはコチラ。

docs.unity3d.com

一部抜粋:

アセットバンドルはダウンロードコンテンツ (DLC) に有用で、初期インストールサイズを削減し、エンドユーザーのプラットフォームのために最適化されたアセットを読み込み、ランタイムのメモリにかかる負担を軽減します。

そうつまり、ストアにアップするアプリのサイズを軽減することが出来るわけですね。
また、コンテンツ配信等にも使用できることになります。
アプリサイズには制約がありますし、サイズが大きくなることでDL数が減る場合もあるそうです。小さくするに越したことはありません。

使ってみよう

開発環境

  • Unity2019.2.21f1
  • Firebase(Authentication、Storage)

サーバーレスを利用する

AssetBundleはサーバーに置いてこそ、その技量を発揮します。
ところが自分みたいな個人開発ですとサーバーエンジニアなんて雇うことはできないし、ましてサーバーの知識なんて皆無なわけで。
ゼロから勉強スタートしてたら、工数がなんぼかかるかわかりゃしない。

そこで役に立つのが、サーバーレスという仕組みです。

詳しくはググっていただくとして(w
めっちゃ簡単に説明すると、サーバー管理は企業がやってくれて、ユーザーはその機能を使うことだけに集中できるシステムです。「レス」だからといって、サーバーが存在しない訳ではないのです。

サーバーレスには色んなシステムがあります(AWSGCPなど)。サービス内容、価格、機能、メリデメ等を比較し、自分に合ったサービスを選択しましょう。
今回はFirebaseを選択いたしました。

Firebaseとは

Googleの提供しているサービスです。以下のようなサービスを利用できます。

  • Authentication
  • Database
  • Storage
  • Hosting
  • Functioins
  • Machine Learning

おまけにUnityに組み込むためのSDKも公開されており、イタレリツクセリ!
リファレンスに沿って、SDKをインストールしておきましょう。
個人利用であれば無料プランで十分だと思います。(従量制プランもあります)

AssetBundleを作ってみる

さっそくUnityでAssetBundleを作ってみましょう!
AssetBundleも色々作り方があるっぽいのですが、私はシンプルにAsset Bundle Browserを使用しました。

Asset Bundle Browserをインストールする

f:id:s44511173:20200727115140p:plain

Package Managerからインストールできます。

AssetBundleにしたいオブジェクトを作成する

f:id:s44511173:20200727121318p:plain

 

PinkとGreenのCubeを2つ作ってみました。あらカワイイ。こいつらをPrefab化しておきます。そしたらSceneからは削除しちゃいましょう。
依存関係の確認がしたいので、PinkCubeをGreenCubeの子供にセットしました。

AssetBundleBrowserWindowを開く

Windowメニューから開くことができます。開いたらタブをどこぞのWindowに入れ込ん
でおきましょう。(そうしないと、次の手順でWindowが背面にいってしまうため)

f:id:s44511173:20200727121022p:plain

「Drag assets here ...」と書かれているところに、先程作ったPrefabたちをD&Dしましょう。

 

f:id:s44511173:20200727121437p:plain

すると、こんな感じになります。GreenCubeの子供のPinkCubeと、それぞれのMaterialが自動的に加えられていることがわかりますね。

Buildする

AssetBundleWindowをBuild画面に切り替えます。BuildTargetとOutput Pathを設定したら、Buildボタンを押下しましょう。

f:id:s44511173:20200727121652p:plain

f:id:s44511173:20200727121947p:plain

ファイルが出力されました。
greencube」がAssetBundleファイルになります。

f:id:s44511173:20200727122438p:plain

greencubeをFirebaseのStorageにアップロードします。これでAssetBundleの準備完了です!

 

AssetBundleを使ってみる

Firebaseのアカウントを作る

Authenticationでユーザーを追加します。開発中はAuthなしでも良いと思いますが、私は練習も兼ねて毎回Authありにしました。
メールアドレスとパスワードでログインできるようにします。

Firebaseを初期化する
// 初期化処理
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
   var dependencyStatus = task.Result;
   if (dependencyStatus == Firebase.DependencyStatus.Available)
   {
// 成功 } else   {
// 失敗
} });

 

Firebaseのリファレンスにあるコードのまんまです。私はこれを見逃していて、いつまで経ってもできずに時間をロスしました(>_<)

Android 向け Firebase Unity SDK には Google Play 開発者サービスが必要であり、SDK を使用する前に最新版にしておく必要があります。

アプリケーションの先頭に次のコードを追加します。SDK で他のメソッドを呼び出す前に Google Play 開発者サービスを確認し、必要であれば、Firebase Unity SDK で必要とされるバージョンに更新します。(C)Firebaseドキュメント

ということで、↑のコードを必ず呼び出す必要があります。

Authする

Firebaseが初期化できたら、作ったアカウントでAuthしましょう。

var email = "xxx@xxxxxx";
var password = "xxxxxxxxxxx";
_auth = FirebaseAuth.DefaultInstance;
_auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(authTask =>
{
    if (authTask.IsCanceled)
    {
Debug.LogError("Auth処理がキャンセルされました"); return; } if (authTask.IsFaulted) {
Debug.LogError("Auth処理が失敗しました: " + authTask.Exception); return; } FirebaseUser newUser = authTask.Result; Debug.Log($"Auth処理に成功しました: {newUser.DisplayName} ({newUser.UserId})");
});

 

AssetBundleをダウンロードする

いよいよ本丸のAssetBundleダウンロードです!!
まずはダウンロードしたいAssetBundleのURIを取得します。

// ストレージアクセスインスタンスの取得
_storage = FirebaseStorage.DefaultInstance;
// 作成したストレージのURIを指定
var storage_ref = _storage.GetReferenceFromUrl("gs://xxxxxxxxxxx.appspot.com");
// ダウンロードしたいAssetBundleのストレージ内におけるパスを指定
var green_ref = storage_ref.Child("Sample/greencube");
// AssetBundleのURIを取得
await green_ref.GetDownloadUrlAsync().ContinueWith((Task<Uri> fetchTask) => {
   if (!fetchTask.IsFaulted && !fetchTask.IsCanceled)
   {
       // 取得成功
       _uri = fetchTask.Result.AbsoluteUri;
   }
});

 

取得したURIを使用して、AssetBundleをダウンロードします。

 using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(uri, version:, crc))
 {
       yield return uwr.SendWebRequest();
       if (uwr.isNetworkError || uwr.isHttpError)
       {
             Debug.Log($"AssetBundleのダウンロードに失敗しました: {uwr.error}");
       }
       else
       {
// ダウンロード成功 var bundle = DownloadHandlerAssetBundle.GetContent(uwr); var prefab = bundle.LoadAssetAsync("greencube");
var cube = (GameObject)Instantiate(prefab.asset); } }

ここでAssetBundleのバージョンとCRCを設定するのですが、これはAssetBundleのBuild時に一緒に出力されたmanifestファイルに記載されています。

実行してみる

f:id:s44511173:20200727135435g:plain

Start()でAuth処理を、ボタン押下でAssetBundleのダウンロード〜Prefabの実体化を行っています。できちゃった!!!
AssetBundleとして作成したのはGreenCubeだけですが、その依存関係にあるPinkCubeとそれぞれのMaterialもちゃんと入っていました。
もしこれらを別々のAssetBundleとする場合、依存関係にあるものを先にダウンロードする必要があるとか。キャッシュのせいでうまくダウンロードできないとか。
まだわかっていない部分が色々あるのですが、その辺は使いながら学んでいければと思っています。

結論

  1. Firebaseを使ってAssetBundleをダウンロードできる
  2. AssetBundle、ハードルは高いけどなんとかなる(今のところ)
  3. Firebaseの設定は結構めんどいので、がんばろう!!!