[unity2019]ReTrace マッピング ファイルがアップできない

Google Play Console にアプリをアップする際、2つの追加情報をアップするよう指示があります。

  • ReTrace マッピング ファイル(.txt または .map)
  • ネイティブデバッグシンボル(.zip)

今回はそのうち、ReTrace マッピング ファイルがアップロード出来なかった顛末と「逃げ気味」対処法です。

unity2019.4.22 で確認しました。

ReTrace マッピング ファイルとは

私も初めて知ったのですが、unity2019 では Android 用のロムをビルドする際に ProGuard という難読化を行っているようです。

ProGuard では、ユーザーのプログラム解析を(いくばくか)阻止したり、動作効率も上がったりするそうです。

Player Settings – Publishing Settings に存在し、次のように設定されていました。

Custom Proguard File にチェックがある
Minify – Release が Proguard になっている

難読化のカラクリ

正確なところは詳しいサイトにゆずるとして、ProGuard は簡単に言えば関数や変数の名前を強制的に変えてしまいます。具体的にはこんなイメージです。

class TestClass
{
    public static void TestMethod()
    {
    }
}

↓

class A
{
    public static void B()
    {
    }
}

「強制的に変えてしまう」ため、アプリ外のメソッドやプロパティ呼び出しも変えてしまい、動かなくなることがある、ということです(さすがに外部のライブラリまで名前は変えないため、不一致になる)。

そのため、Google の Ads などを使っている場合、proguard-user.txt に難読化を抑制する記述が書かれます。

-keep public class com.google.android.gms.ads.** {
   public *;
}
-keep public class com.google.ads.** {
   public *;
}

Google Play Console 提出用パッケージを作成する

以上の設定を前提として、Google Play Console 提出用パッケージを作成します。

Build App Bundle (Google Play) にチェックを入れる
Create symbols.zip にチェックを入れる

この状態でビルドすると、以下の3ファイルが作成されます。
(tataq の部分は任意名です)

aab apk の進化系ファイル(のよう)です。ARMv7 ARM64 の環境を容量の無駄なく(ユーザーに)効率的に配布できる、との事。

正直、Android よくわからないので、だいたい maybe

unity では、Build SettingsBuild App Bundle(Google Play) にチェックを入れると aab ファイルが作成できます。

keystore を作成していない場合、以下のエラーでビルドできません。
別の記事にしましたので、こちらをご覧ください。

Google Play Console にアップロードする

Google Play Console 開設については他記事をご覧ください。ここでは、アプリのアップロードについて説明します。

とりあえずクローズドテストで確認し、大丈夫ならリリース…という手順がいいと聞きましたので、まずは以下の画面に aabファイルをドラッグ。
クローズドテストなんて必要ない剛の方は、製品版を選んで同じことをします。

aabファイルをオレンジの枠にドラッグ

3点リーダをクリック

ReTrace マッピング…を選択

mapping.txt をドラッグ

ここでエラーに…

このようなエラーで先に進むことができませんでした。

なお、ネイティブデバッグシンボル .zip は 300MB 以内であればアップロード可能。それ以上のサイズであれば一旦解凍し、7zip などで再圧縮すれば 300MB になると思います。

この件に関してググってみた

似たような問題を抱えている人をググってみましたが、ほとんどは map ファイルの作り方や、(ファイルが)どこにあるかといったものであり、「Play Console でエラーになる」という質問は1~2件ほどあれど、回答もなく放置されているようでした。

Google Play Console に聞いてみた

その件は unity の問題ですので、お答えしかねますとの回答。

unity には聞けなかった

サポートは「サブスクリプションに登録」「英語のみ」との事。私は無料アカウントで制作しているため、こちらに頼ることはできませんでした。

Android Studio で作成したアプリを確認

Android Studio だとどうなるんだろう?」と思い、Hello World を表示するだけのアプリで aab ファイルを作成しました。

それを Google Play Console にドラッグしたところ、自動的にマッピングファイルが登録されている…。

Android Studio 4.1.1 にて確認。そもそも aab ファイルの中にマッピングファイルは同梱される?

2つのマッピングファイルを比べてみる

unity で出力されたマッピングファイルと、Android Studio で出力されたファイルを比べてみました。
Android Studio はただの Hello World を表示するアプリなので、unity の方がさぞかし多いんだろうと…そんなことはなかった。

unity のファイル

たったこれだけ。
アプリコードの難読化リストとかあるのかと思っていたので、拍子抜け。ProGuard はアプリコードの難読化をしてるようには見えません。

それとも、ProGuard ちゃんと使おうとしたら、他にも色々設定が必要なんでしょうか。

# compiler: R8
# compiler_version: 1.4.77
# min_api: 20
com.google.androidgamesdk.ChoreographerCallback$1 -> com.google.androidgamesdk.a:
com.google.androidgamesdk.SwappyDisplayManager$1 -> com.google.androidgamesdk.b:
com.google.androidgamesdk.SwappyDisplayManager$a -> com.google.androidgamesdk.SwappyDisplayManager$a:
    com.google.androidgamesdk.SwappyDisplayManager b -> d
    java.util.concurrent.locks.Condition d -> c
    java.util.concurrent.locks.Lock c -> b

Android のファイル

こちらはビックリ、25000行近くの難読化リストでした。
あらゆる変数・メソッドを難読化しているようです。

# compiler: R8
# compiler_version: 2.1.75
# min_api: 19
# pg_map_id: 415b558
# common_typos_disable
androidx.activity.Cancellable -> a.a.a:
androidx.activity.ComponentActivity -> androidx.activity.ComponentActivity:
    androidx.activity.OnBackPressedDispatcher mOnBackPressedDispatcher -> f
    androidx.lifecycle.ViewModelStore mViewModelStore -> e
    androidx.lifecycle.LifecycleRegistry mLifecycleRegistry -> c
    androidx.savedstate.SavedStateRegistryController mSavedStateRegistryController -> d
    1:1:androidx.savedstate.SavedStateRegistryController androidx.savedstate.SavedStateRegistryController.create(androidx.savedstate.SavedStateRegistryOwner):0:0 -> <init>
    1:1:void <init>():0 -> <init>
    2:2:void <init>():0:0 -> <init>
    androidx.lifecycle.Lifecycle getLifecycle() -> a
    androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher() -> c
    1:1:androidx.savedstate.SavedStateRegistry androidx.savedstate.SavedStateRegistryController.getSavedStateRegistry():0:0 -> d
    1:1:androidx.savedstate.SavedStateRegistry getSavedStateRegistry():0 -> d
    androidx.lifecycle.ViewModelStore getViewModelStore() -> e
    void access$001(androidx.activity.ComponentActivity) -> i
    1:1:androidx.lifecycle.Lifecycle getLifecycle():0:0 -> onSaveInstanceState
    1:1:void onSaveInstanceState(android.os.Bundle):0 -> onSaveInstanceState
・
・
・
(全24959行)

unity2019 ではほとんど難読化できてないんじゃ?

unity サイドで作成されたマッピングファイルはたった数行、しかも見覚えのない Google や java のメソッド難読化してるだけなら…。

難読化しなくていいんじゃない?

それでも諦めず unity プロジェクトを Android Studio にエクスポート

Android Studio で開ける形にエクスポートできるようなので、そちらでコンパイルしたらもしや?

結果のマッピングファイル

# compiler: R8
# compiler_version: 2.1.75
# min_api: 20
# pg_map_id: b8138aa
# common_typos_disable
com.google.androidgamesdk.ChoreographerCallback$1 -> com.google.androidgamesdk.ChoreographerCallback$a:
com.google.androidgamesdk.ChoreographerCallback$a -> com.google.androidgamesdk.ChoreographerCallback$b:
com.google.androidgamesdk.SwappyDisplayManager$1 -> com.google.androidgamesdk.SwappyDisplayManager$a:
com.google.androidgamesdk.SwappyDisplayManager$a -> com.google.androidgamesdk.SwappyDisplayManager$b:
    java.util.concurrent.locks.Condition d -> c
    java.util.concurrent.locks.Lock c -> b

Gradle のバージョンが変わり、少しだけ出力内容が変わりましたが、unity であろうと、Android Studio であろうと内容はそれほど変わりません。
また、このマッピングファイルもアップロードできませんでした。

[解決]もう…難読化をやめよう

根本的な解決とは思えませんが、マッピングファイル見た感じ unity ではほとんど難読化も行われていませんし、ProGuard は諦めました。

なお、Play Console ではマッピングファイルがないので「難読化されている可能性があります」と警告が出ますが、そもそも難読化していないので、こちらは無視で構わないと思います。

いつかは解決したい…

2件のコメント

  1. どうしてエラーになるんでしょうね。
    私とやり方は同じでした。

    最近プロガードしてるのにマッピングテキストが初めから登録されるようになっていました。
    初めから3点リーダの一番上が登録済みです。

    フォントが落ち着いていて良い雰囲気のブログですね。

    1. キリンさんは問題なく登録できていたのですね。
      時期やバージョンによって、出来たり出来なかったりもあるのかなーと思いつつ、備忘録的に記事にしました。
      (デバッグに関しては Firebase の方でなんとかしちゃってるので、Play Console はいいか…と、さっさと見切りをつけました 笑)

      お褒めいただき嬉しいです。有難うございます!

返信を残す

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

CAPTCHA