Unity Crash ***/level***
こんにちは。4年前に一度ブログ担当したプログラマの藤原です。つい最近携わっているUnityプロジェクトで発生したエラーについて書こうと思います。
特定の画面へ遷移しようとするとiOS/Androidで100%強制終了
強制終了…プログラマーなら冷や汗かく報告を受け、直ぐにAndroid端末のログを確認したところ以下エラーが発生していました。
E Unity : The file '/data/app/****/****/base.apk/assets/bin/Data/level0' is corrupted! Remove it and launch unity again!
※ちなみに level0 や level124 など画面毎で違う
続く報告で「数日前のビルドだと大丈夫でした」とのこと。数日前から報告受けたビルドはコード変更はしていなかったので、頭にハテナを浮かびつつ調査した結果、以下のようなコードが原因でした。
class Hoge : MonoBehaviour
{
if ENABLE_HOGE
[SerializeField] GameObject goHoge;
endif
~省略~
}
※ENABLE_HOGEはプロジェクト固有のもの
UnityのScripting Define Symbolsに上記シンボルが追記されていれば変数を使えるようにしている一見よくあるコードですが、 SerializeField を使ってシーンやプレハブのインスペクターから編集可能としているのがダメでした。
「ちょっとまて。なぜダメなんだ?」と思った人は鋭いです。前述した通り大丈夫だった数日前のビルドにも入っているコードなのに、なぜ急にダメになったのか。
シンボル切り替え直後のビルドでクラッシュ再現
不具合報告受けたビルドですが、シンボルを追記した直後のビルドだったようで、これが再現条件でした。
先ほどのダメな変数用のシンボルを追記するとスクリプトファイルが再コンパイルされます。その後、シーンやプレハブのインスペクターから編集可能となるのですが、このUnity側の更新が若干遅れるみたいで、切り替え直後のビルドだと更新が間に合わず、正しく動作しないクラッシュビルドが生まれたわけでした。
解消方法として以下3つになります。
- インスペクター用の変数を#if~#endifで括るのをやめる
- Scripting Define Symbols 変更後にUnity更新されるまでちょっと待つ
- 該当シンボルが有効と無効なものでビルドプロジェクトを分ける
おすすめは一番上なのですが、プロジェクト都合もあるので適宜ご判断ください。
とりあえず、今回のようなコードは二度と書かないように心に誓いました。
以上、タイムリーな制作現場の日常でした。
おまけ:赤ちゃんとリモートワーク
入社してから4年ほど経つのですが、東京から静岡へ引っ越し、結婚してもうすぐ1歳になる娘が生まれるなど仕事環境がガラリと変わりました。
娘が生まれる前は「世話しながら仕事ができるのかな」と思っていた時期がありましたが、奥さんが育休中のおかげで特に問題はありませんでした。平日は仕事前の離乳食、お昼休憩中の離乳食、夕方のお風呂の出し入れ、たまにオムツ変えたり、あやしたりするくらいです。
任せっきりで申し訳ないのですが、奥さんは「出社してると全部ワンオペになるから、むしろ私が助かる」と言ってくれて自分も助かってます。奥さん様様です。
正直集中できないときもありますが、それ以上に疲れを癒してくれて次の仕事も頑張ろうという気持ちにもなります。
奥さんに感謝され、子供から癒され、成長をじっくり感じられる赤ちゃんとリモートワークは個人的におすすめです。
以上、遠方からリモートワーク環境下で子育てするちょっと特殊な会社員の話でした。