【Unity】AppStoreReviewガイドラインの『4.2 最低限の機能』を満たす為にチュートリアルのアセットをiOSのみアプリ組み込みにした話

はじめに

こんにちは、ソーシャルゲーム事業部 ゲームチーム所属の須藤 (@p_chin) です。 この記事はカヤックUnityアドベントカレンダー2018の19日目の記事になります。

今回はAppleのiOSアプリの審査に通る為に試行錯誤した知見について書こうと思います。

最近App Store Reviewガイドラインに以下の項目が追加されました。

(ii)起動時にAppが正しく機能するよう、バイナリに十分なコンテンツが含まれるようにしてください。

上記項目に対して未対応の場合には審査でリジェクトされるリスクがあるので、対策を考える必要があります...。

私の所属プロジェクトではこれを 『一通りプレイしてどんなゲームであるかをユーザーが理解でき、追加ダウンロードするかどうかをユーザーが判断できるだけのコンテンツがアプリに内包されている必要がある』 と解釈して対応を進めていきました。

ちなみにアプリのダウンロードサイズを減らしたり、アプリのアップデート無しでアセットを更新する為に、アセットは追加ダウンロードにするのが一般的です。

チュートリアルのアセットを組み込みにする対応についてまずは方針を考えた

これを考え始めた時点で、チュートリアルのAssetBundle(以降はABと書きます)は起動後のダウンロードで取得する実装になっていました。

まず最初に、やり方は二つのパターンがあるかなと思ったので検討してみました。 ちなみに今回対応したのはiOSのプラットフォームのみです。Androidが未対応な理由は後述します。

  • StreamingAssetsフォルダにABを置くパターン
  • AB化せず、素材をそのままResourcesフォルダに置くパターン

調査+比較した感想としてはStreamingAssets案がバランス的に良さそうだと思ったのでそちらを選択しました。 理由は以下になります。

  • ビルド後の置き場所を変えるだけなので、ビルド処理の改修範囲が少ない実装で実現できそう
  • 元々全てのアセットをABからロードしていたため、ABからロードできた方が改修範囲が少ない

Androidを今回の対応から除外した件について(おまけ)

本当はAndroidもiOSと一緒にチュートリアルのアセットを組み込みにする案についても考えていました。 しかしapkサイズが増えてしまうのと、iOSのみ処理を分けるのがそれほど大変では無かったので選択しませんでした。

また、Androidも対応してしまうとapkサイズが100MBを超えてしまう状況でしたので、APK拡張ファイルの追加を行わないといけませんでした。

正直それは面倒臭いなぁと思ったので対応したくありませんでした。

具体的な実装について

私のプロジェクト上では元々チュートリアルの為に 『ABのダウンロードタイミングの辞書が入ってるScriptableObject』 を作っていました。 それをビルド処理中に読み、チュートリアル中に使われるABファイルならStreamingAssetsにABファイルを配置する様に実装することで、割と簡単に対応できました。

またStreamingAssetsは全てのプラットフォームでビルドに含まれてしまうので、Androidのビルド時にはフォルダ内のABを全て削除する対応も行いました。

ABのダウンロードタイミングの辞書が入ってるScriptableObject(おまけ)

こちらが意味不明だと思いますので、補足します。 私のプロジェクトでは元々チュートリアルをプレイする前の大容量アセットダウンロードはユーザーの勢いを殺してしまうので抑える方針でした。 なので、チュートリアルに入る前はチュートリアルに必要なアセットしかダウンロードしない様にしていました。 その時にこちらの機能を実装していた経緯があります。

チュートリアルで使うかどうかの判別方法ですが、UnityEditorでの再生時にロードしたAB名を記録するようにしてあり、手動でチュートリアル完了までゲームを進めることでチュートリアルに必要なABを特定できるようになっています。 全自動の方が安全ですが、チュートリアルはそんなにコロコロ内容が変わらないと思うので、あまり頑張っていません。

f:id:pchin:20181217181837p:plain
AssetBundleのダウンロードタイミングの辞書ファイル

実装後に出た問題について

iOSのみチュートリアル素材を組み込みにした事によって 『どれがビルド更新必要』で『どれが必要ない』 の判断が難しくなってしまいました。 エンジニア以外の職能が自分でABをビルドして、それを実機確認する際に問題が発覚しました。 その複雑性を解消するアイデア+仕組みを考える時間が必要そうです。

問題を整理してみます

  • 『組み込み』『組み込みじゃない』アセットの区別が判断しにくい
    • どれがチュートリアルに入ってるか?など
  • チュートリアルに含まれてるアセットを更新したいとき、iOSの場合はアプリの更新が必須になる
    • チュートリアルのアセットの更新を実機確認したい人はアセット更新の度にビルドを作ってインストールする必要があった

解決方法

松竹梅でアイデアを出し、まずはチームメンバーと相談しました。今回は竹梅プランを選択しました。

  • ABビルド時に組み込みになったAB名のリストをSlackに通知する仕組みを作る

  • チュートリアルが終わった後にWebから最新のABをロードして更新可能にする
    • 同じ種類のABを持つ事になるのでアプリサイズが余分に150MBほど増えます
      • ex) チュートリアルに含まれるAの3Dモデル+最新のサーバーから配信されてるAのモデル

  • ABになってるアセットの確認を簡単にするために、『全てのABをWebからロードするモードに切り替える』デバッグボタンを実装する
  • ABビルド時にiOSで組み込みになるABは差分が確認できる様にする

以下の画像の様に、AB素材を追加したプルリクエストで assetbundle {branch_name} とコメントするとビルドが始まり、チュートリアルのABも更新された場合にはついでにStreamingAssets以下にABを追加するcommitを作ってくれます。

f:id:pchin:20181217181742p:plain
AssetBundleをビルドした後にStreamingAssetsへの更新をbotがcommitしてくれる図

最終的にやった事のまとめ

  • チュートリアルで参照するABをiOSの場合のみStreaminagAssetsに置いて、Webからロードする必要を無くした
  • アセットの更新のためにアプリのアップデートが必要になる制限はやりにくいので、チュートリアル突破後はチュートリアルで使うABもWebからロードする様にした
  • 全てのABをWebからロードするデバッグ機能を作成して、単純なアセットの実機確認で今回の対応が枷にならない様にした

おわりに

今回は一つの事例として紹介しましたが、同じ様にチュートリアルのアセットを全て組み込みにする境遇の方がググった時に見つけて参考にできれば幸いです。
明日は大谷による UnityでLINQのパフォーマンスの比較 の話になります。

参考資料

http://tsubakit1.hateblo.jp/entry/2016/05/07/073000