TOPICS

TECH BLOG

【TECH BLOG #19】Unityアップデートで悩む日々・・・

#Unity #Unityアップデート #Platform対応

はじめに

ファンプレックス株式会社 エンジニア部 技術戦略チームのアンドゥです。

最近、社内の取り組みの紹介が多かったので、少し技術寄りの話をしたいと思います。
文章ばかりになってしまいましたが、ご一読頂けると幸いです。

Unityのアップデートについて

ファンプレックスでは複数のタイトルを移管&運営していますが、その中にはゲームエンジンとしてUnityを使用しているものが複数あります。

Unityはゲームエンジンなのでアプリの基盤であり、滅多なことがない限りバージョンの更新などは行いません。

しかし、昨今のAppleやGoogleの規約変更の為にUnityのバージョンアップを実施する必要が出てきています。

決定的だったのが、Androidの「64 ビット アーキテクチャのサポート」 対応です。

https://developer.android.com/distribute/best-practices/develop/64-bit?hl=ja

この対応はUnityの古いバージョンではサポートされておらず、対応されているバージョンへのアップデートが必須です。
さらに、対応の期限が2019年7月31日まで(Unity5系のバージョンは2021年7月31日まで)とされていました。

3年ほど前に戦々恐々とした思い出があります。

実は・・・

私自身、2つのタイトルでUnityのアップデートを行っています。

1つ目(1年半前)   :Unity5.4からUnity2018.4.0f1へ
2つ目(現在進行中!):Unity5.6からUnity2018.4.27f1へ

前提として、
弊社のほぼ全てのタイトルが他の会社様の作り上げたゲームシステムやソースコードを運用しています。
我々としては、それらを理解して対応しなければならないので、機能の修正や追加などをするだけでも細心の注意が必要です。
ましてや自分達が設計していないシステムのUnityアップデートはいくつもの罠が存在しました。
今回はそんな罠をいくつか紹介していきます。

1つ目のタイトル

1つ目のタイトルは弊社内でも初めてのUnityアップデートタイトルだった為、情報も少なく手探り状態で作業していた記憶があります。

その際に以下の様な多くの問題が発生しました。

 ・TextureTypeが無くなった
 ・ShaderファイルのUnity自動ファイル更新でゴミ文字が混入
 ・全角文字を含むファイルを読み込んでくれない
 ・Android 64K問題 
 ・StackOverflowException発生
 ・UniRx Pluginアップデート 
 ・Conditional属性が設定された関数が呼び出されない 
 ・Androidアプリの100MiBサイズオーバー
   などなど

中でも注目&被害の大きかった問題はの付いている3つです。

罠1:Android 64K問題


これはAndroidアプリをビルドする際に発生するエラーです。

> trouble writing output: Too many field references: 67790; max is 65536.

【原因】
無駄なライブラリがいっぱいで、アプリ内のAPIがAndroidの制限を越えた為。
特に分析で使用していた異なる外部ツールのSDKのバージョンが噛み合っていない。

【解決策】
パブリッシャー様から貰っていたjarファイルを破棄。
Gradle(build.gradle)で適切なバージョンのjarファイルを取り込むように修正。

【教訓】
無駄にSDKを導入しない。

パブリッシャー様やPD/PLの方々はいろいろな種類のデータを求めるあまり、さまざまなシステムを導入しがちです。結果、アプリサイズが増えますし、最終的にはこのような問題も発生してしまいますので分析ツールはまとめた方が良いです。
(このタイトルでは最終的に不要と判断された分析のSDKを1つ削除しました)

ちなみに弊社では現在、各タイトルで使用しているSDKやossなどを洗い出し、定期的に棚卸しを実施する事で無駄なものが増えないような取り組みを行っております。

罠2:UniRx Pluginアップデート


UniRxとは、デザインパターンの一つであるObserverパターンを基に設計された、非同期処理用のライブラリです。
これもUnityのバージョンに合わせてアップデートを実施する必要がありました。

UniRxはpluginなので、基本的にファイルを上書きするだけ!と思っていたのですが、
アップデート後にコンパイルエラーがたくさん出ました。。。

【原因】
ライブラリであるUniRx のソースコードに変更が加わっていた。

【解決策】
コードの修正部分を見つけ出し、ひたすら手作業で直す。

【教訓】
移管されたライブラリはコードに変更が入っている前提で対応する。
そして、自分達はライブラリのコードをむやみに変更しない。
   
Gitの履歴が残っていたり、使用したライブラリのバージョンが分かればまだ良いかもしれませんが、それらの情報が無いと大量の変更点が有った場合は厳密なコード反映など不可能に近いです。
もし、ライブラリに手を加える場合はその部分が分かりやすい様なコメントを記載したり、資料を残しておき、のちの更新がスムーズに行えるようにヒントを残しておくと良いです。

罠3:Conditional属性が設定された関数が呼び出されない


これはリリース後に発覚した不具合です。
分析データの送信に影響が出ました。。。

現象としては、C#のConditional属性を設定されていた初期化処理の関数が呼び出されなくなり、その後の処理が正常に行われなかった、といったものです。

【原因】
(おそらくですが、)ファイルのビルド順がUnityアップデートにより変わってしまった為。
事実、Conditional属性で使用するシンボルを定義するファイルを変更すると正常に動作しました。

【解決策】
Conditional属性を削除。(そもそもこの属性付与自体に意味がなかった!?)

【教訓】
デバッグシンボル以外にConditional属性を使用しない。

Conditional属性は、様々な資料で”DEBUG”などのビルドの最初から最後まで存在するシンボルを使用している例がほとんどかと思います。しかし、この時使用していたシンボルはソースコード内で定義しているもので、ファイルのコンパイル順によってシンボルが存在する/しないタイミングが発生してしまいます。
そもそも、C/C++とは異なり、C#はソースコードのコンパイル順を意識しない言語ですので、不具合の出たソースコードはたまたま動いていたに過ぎないかと思います。

更に、定義したシンボル内でDEBUGシンボルを使用しており、処理的にもConditional属性の意味がありませんでした。。。従って、Conditional属性自体を削除した次第です。

ソースコードも変えていないこの不具合の検知は困難を極めます。
この例を教訓にソースコード内にConditional属性を見つけたら、使用しているシンボルを必ず確認した方が良いです。

2つ目のタイトル

2つ目のタイトルは移管の時からUnityアップデートを視野に入れて動いています。
以下の点は開発移管元へ念入りに確認していました。

 ・独自作成のライブラリがないか?
 ・ライブラリに手を加えている箇所はないか?

幸い、そのような事はなく、
またシステム自体がパブリッシャー様のものを使用している為に安心していました。
そしてそこにこそ罠がありました。。。

罠4:リリースの1ヶ月前倒し(現在進行中)


予定ではアプリのイベントスケジュールも考え、2021年3月リリースを目指していたところ、突然、パブリッシャー様からリリースを1ヶ月前倒しにして欲しい旨の依頼が有りました。
結果、前回の経験を元に危険性を十分に共有した上でも、運営都合上1ヶ月の前倒しをせざるを得なくなってしまいました。。。

パブリッシャー様自体も他のタイトルでUnityアップデートの実績があり、その資料を見ながら対応すれば間に合うだろうとの計算があったかもしれませんが、そんなにスムーズには事が運びません。

特にAndroid 64bit対応が決定的に違いました。
Androidでは、Googleストアにアプリを提出する際、ファイルサイズを100MiB以下にする制限があります。
パブリッシャー様のタイトルでは32bit版と64bit版を1つのapkファイルにギリギリ納めていた様でしたが、弊社で扱っているタイトルはどうしても制限を越えてしまいます。

【解決策】
AAB(Android App Bundle)ファイルで作成&提出する。

1つ目のタイトルではパブリッシャー様のシステムがAABに対応できていなかった為、32bit版と64bit版のapkファイルを別々に作成しました。
今回はAABファイルでも対応可能との事だったので、Google推奨でもあるAABを採用です。
ただし、新しい仕組みの為にビルドシステムを改良したり、環境を構築する工数が発生します。
Unityアップデートに限らず、「資料があるからサクッと出来るだろう」との考えは注意した方が良いです。

罠5:AppleのPlatform対応(現在進行中)


上記、1ヶ月前倒しの原因はAppleのPlatform対応の為で、パブリッシャー様のツールがかなり影響を受けていたようです。
中でもAppTrackingTransparencyフレームワークによるポップアップ表示の実施タイミングや対応方法をパブリッシャー様でも迷っている様でした。
我々はUnityアップデートの為にそちらまで手が回らずに、パブリッシャー様へ質問や矛盾点を尋ねていたのですが、最終的には”Appleの動向が分からない”との事で個人的にはスッキリしない状態です。
※2021/1/28にAppleの追加情報あり(https://developer.apple.com/jp/news/?id=8rm6injj

【教訓】
今回の反省点として、我々のパブリッシャー様のツールに対する理解が十分に出来ていなかった事かと思います。
対象のツールはゲームシステムには直接影響ないものだった為、理解の優先度が低かったのも事実です。
今後はそれらのツールがどのようなものなのか?を概要だけでも早めに理解し、Platform対応の際にはどのように影響が出るか?などを注視したいと思います。

また、今回はAppleの動向をパブリッシャー様に尋ねる他ありませんでしたが、今後は弊社でも新規タイトルを扱っていくので、AppleやGoogleとの窓口を何かしら準備する必要があるのでは?と個人的に思いました。まずはグリーグループ内での窓口と連携を開始出来ればと思っています。

最後に

2つ目のタイトルは現在進行中のもので、リリース間近となっています。
前回もそうでしたが、リリース日が近づくにつれて、胃が痛くなってくる思いです。

Unityアップデート自体はそれほど難しくないかもしれません。
しかし、その他のライブラリやツールなどに大きな影響が有ります。
従って、Unityアップデートの作業はその影響の一つひとつを解消していく事かと思います。

これからはUnity5系から20XX系への様な大規模な変更のあるアップデートはあまりないかと思いますが、
今後は定期的なゲームエンジンのアップデートも視野に入れて、移管や新規アプリの開発に努めると共に情報共有やルール作りなども行っていければと思います。

また、今回のアップデートに向けて進めていた自動テストの作成が間に合いませんでした。。。
今後はその自動テストの仕組みを完成させ、アプリの大規模変更がより安全に出来るように努めていけたらと思っています。その話はまた後日!

ファンプレックス株式会社

グリー株式会社の100%子会社で、ゲーム運営を軸にした事業を行う。
公式サイト: https://funplex.co.jp/
公式Facebook:https://www.facebook.com/funplexInc

[本件に関するお問い合わせ先]
ファンプレックス株式会社 広報担当
東京都港区六本木6-10-1 六本木ヒルズ森タワー
E-mail: info.funplex@funplex.co.jp