【Unity】ビルドして分かるエラーもあるので定期的なビルドがおすすめ
リリース先のプラットフォームに向けたビルドは個人開発だと開発の後半に回してしまいがち。特にUnityエディタでのテストが完了した後に、「さあリリースだ!」と意気揚々と実機ビルドをすることも多いかもしれません。このタイミングでは多くの場合、ビルド時に初めて分かるエラーなども発生するので、エラーの量によってはテスト完了後のリリース計画を練り直すこともあります。
そのため、定期的なビルドを行なっておくことで早めにエラーを検知しておくのがおすすめです。特に外部ライブラリを使っていると依存関係によるエラーが発生したりするので、どこまでが自分の作業によるエラーなのか、どこまでがライブラリ側のエラーなのか、といった点を切り分けられるように、ライブラリ導入前後でそれぞれビルドするのも良いかもしれません。
よくありがちなエラーシリーズ
挙げたらキリが無いシリーズですが、パッと思いつく範囲で以下のものがあります。
- エディタ用のクラスをインポートしている
- ライブラリの依存関係
- AndroidのMinify関連
- AndroidのSDKやNDKのパスが通っていない
- Androidのマニフェストファイルの記述ミス
- モバイルのネイティブプラグイン関連
エディタ用のクラスをインポートしている
作成したスクリプト内で「import UnityEditor;」またはUnityEditorの下にあるクラスを使っている場合にエラーが出ます。UnityEditorの下にあるクラスはその名の通りUnityエディタで使用するクラスで、ビルド時にはエディタ関連のライブラリが含まれないようになっています。
いわゆるエディタ拡張のスクリプトファイルを作成する場合は、Projectウィンドウで「Editor」という名前のフォルダを作成してその中に配置するのですが、Editorフォルダ以外でUnityEditor配下のクラスを使ったスクリプトを配置すると、ランタイムに含めることができなくてコンパイルエラーになります。
解決策としては「import UnityEditor;」の記述があるスクリプトファイルについては「Editor」フォルダの下に配置します。
参考
ライブラリの依存関係
外部のライブラリを導入すると発生しがちなビルドエラーです。個人的にはFirebase関連で発生することが多いような気がします。と言いつつ、近年のFirebaseだと依存関係の解決用ツールが付属しているので、頻度は減ったような印象です。
使っているライブラリによって異なるのが厄介なところですが、ありがちなのはgithubで公開されている2つのライブラリを導入したら、それらのライブラリが内部で参照しているDLLが一緒だった、みたいなケースでしょうか。インポート時にコンパイルエラーが出て気付くことも多いかと思いますが、ビルド時まで気付かないケースもあります。
そのライブラリをいつ導入したか、という点はメモしておくと良いかもしれません。この部分はgitを使ってコミットしておくのが簡単ですね。
AndroidのMinify関連
Player Settingsの「Publishing Settings」の項目で設定できるMinifyは、ビルド後のコードを最適化や難読化することで容量を節約できる機能です。使っていない変数やクラスなどはビルド後のコードから削除されたり、名前が短いものに変更されたりしますが、たまーにこれがビルドエラーの原因になったりします。
というのも、文字列を使ってクラス名やメソッド名を特定しているものなどは、名前変更の際に参照が分からなくなってしまいがちなので、ビルド時に必要なクラスが見つからずにエラー、なんてことがあります。機械的に参照関係が分かれば一緒に名前を変更してくれますが、文字列だと参照されているのかどうかが分からないので、実体のクラス名だけ違う名前、文字列はそのまま、結果クラス名が不明に……なんて流れになります。
ネイティブプラグインを使ってOSの機能を呼び出している場合には、文字列で指定する必要があるケースもあり、Minifyによって消されている(あるいは名前が変更されている)ことも。
この点に関しては、UnityのMinifyの機能では内部でProguardを使っているので、Proguardのルールファイルを使ってクラス名を変えないようにするのが対策になります。
Minifyの設定によっては、本番用ビルドのみ圧縮する設定にしていることもあり、開発用のビルドでは見つからなかったけど、本番用のビルドで初めてエラーを検知するケースもあったりします。Minifyはビルド時間にも影響するため、開発用ビルドでは無効化してビルド時間を短縮し、本番用ビルドでは難読化する、というのはUnity推奨の設定なので、気付くタイミングがリリース前になりがちなのが厄介な部分です。
参考
AndroidのSDKやNDKのパスが通っていない
UnityのPreferencesウィンドウにある「External Tools」の項目ではAndroidのSDKやNDKへのパスを設定できます。
Unity Hub経由でAndroid SDKやNDKをインストールしている場合、あまりきにする必要が無いケースかもしれませんが、Android Studioを先に入れていて、後からUnityを入れた場合などにはAndroid SDKやNDKのパスが意図しないパスになっていることもあるので、確認しておくと良いかもしれません。
Androidのマニフェストファイルの記述ミス
いやほぼAndroidやんけ!
とツッコミ待ちのような流れになっていますが、事実Android向けのビルドはエラーが発生しやすい部分です。一回Xcodeを通すiOSと違って、Unityだけでそのままapk(あるいはaab)ファイルを生成できるAndroidだと、ここでのビルドが最終関門になるため、ちゃんとチェックされるのはある意味安心できるポイントかもしれません。
AndroidのマニフェストファイルはUnityが自動生成するものを使ったり、カスタマイズしたものを使ったりできます。ビルド前にマニフェストファイルの内容まではチェックされないため、ビルドしてみて初めてマニフェストファイルの記述ミスに気付くケースがあったりします。
対策としては、apk(あるいはaab)ファイルを生成する前に、Androidのプロジェクトとしてエクスポートして、Android Studioを使ってプロジェクトを開き、マニフェストファイルのインテリセンスを使ってエラーをチェックする方法があります。チェック機構のある環境でファイルを開いて、そこで修正してUnity内のファイルに反映し、最終的なパッケージファイルをビルドすることで、エラーの検知がしやすいフローになります。1回分ビルドが増えますが、Unity内だけでマニフェストファイルをいじっていると、どこがエラーになっているのか分かりにくいので南無三ビルドを何回もやることになるケースも。
自分で作成したマニフェストファイルの場合はある程度自分で制御できるものの、外部ライブラリに含まれているマニフェストファイルと競合していることもあるため、導入した外部ライブラリにあるマニフェストファイルについては全てチェックしておいた方が無難です。
モバイルのネイティブプラグイン関連
モバイル向けのアプリを作成する場合、iOSではSwiftのコードを呼び出したり、AndroidではJavaのコードを呼び出したりすることができます。文字列を使ってクラスやメソッドを呼び出している部分があったりすると、このズレでコードの呼び出しができずにビルド時にエラーが表示されることが多いです。
先述のMinifyの部分と関連するところもありますが、Minifyでクラス名がリネームされることで呼び出し先が分からなくなったり、単純に自分で呼び出す対象のクラス名を間違えていたりと、文字列による指定はエラーの温床になったりするんですよね。
AndroidだとAndroidJavaObjectを使ってJavaのクラスを呼び出したりもしますが、引数として文字列でクラス名やメソッド名を渡す必要があり、間違えやすい部分になっています。C#側のコンパイルだと文字列として扱われるのでエラーが出ず、ビルド時にAndroidアプリ向けにGradleを通したタイミングで文字列の記載が間違っていたことに気付いたりも。
対策としては呼び出し元で記載しているクラス名、メソッド名をよく確認する、という基本的な部分が肝心でしょうかね。
定期的なビルド、しよう
冒頭に書いた通り、定期的なビルド大事。ほんと。
モック版を作っている段階だと、アイディアを練っていく方に時間を使いたいのでそこまで頻繁には必要ないかもしれません。だんだんと開発が進んできて、ある程度エディタ上でも動作するようになったら、エディタ上でのデバッグ作業に加えてビルドだけでもしておくとグッド。
ビルドに時間がかかる場合は、休憩前にビルドを開始しておけば時間も無駄にならないかもしれません。昔会社の先輩に聞いていた話だと、ビルドに時間がかかるマシンだったことから、ビルドの時間はコンビニタイム、と割り切っていたようです。こんな感じで、風呂入る前にビルド、ご飯食べる前にビルド、と手が止まるタイミングでビルドしておくと良さそうです。この辺は開発リズムに合わせてうまく調整してくださいな。
リリース直前に新しいエラーを見つけるのが一番メンタルにダメージを負うので、いかに早い段階で検知するかはとても大切ですね(1敗)
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】なかなか環境に恵まれないRPG Maker Uniteちゃん 2023.11.09
-
次の記事
【Unity/C#】DictionaryでTryGetValueのメソッドを使って処理速度を比較 2024.11.14
コメントを書く