もんりぃ is undefined.

育児ネタとか、技術ネタとか。

Unity を batchmode で起動した場合に EditorApplication.update が走らないコトがある問題

前提

  • 今、お仕事で「Jenkins 上で AssetBundle のビルドを走らせて、終わったら差分を S3 に上げつつ GitHub にも push して PullRequest を作る」という仕組みを作ろうとしています。
  • そのためには、 -batchmode というコマンドライン引数を付けて、 -executeMethod 引数で実行する public static な自作メソッドを指定して Unity を起動したうえで、そのメソッド内で BuildPipeline.BuildAssetBundles() なるメソッドを叩く必要があります。
    • いや、 -batchmode 使わない方法もあるかもだけど、CI する上ではほぼ必須のオプションだと思ってます。
  • で、更に、処理が終わったら自動的に Unity Editor が Exit して欲しいので -quit オプションも付けます。

現象

  • 非同期なコードが一切実行されない!
    • 最初は UniRx を使って async/await を使う感じの実装にしてました。
    • で、動かないんで「async/await だめかー。素直に UniRx で SelectMany とか Concat とかで処理繋ぐかー。」って書き換えてもダメ。
  • というか、ログを仕込んで確認したところ UnityEditor.EditorApplication.update がコールバックされている気配がない。

調査

  • Unity Answers で同じような悩みを持つ人の質問を発見。
    • 回答曰く「 -batchmode でも EditorApplication.update 動くよー」トノコト。
  • 更に深掘りしてググった所 -quit が怪しい説に辿り着く。*1
  • で、試しに -quit を外したところ見事に動く。
  • 推測も含むが、 EditorApplication.update のコールバックが発動するのは -executeMethod で指定したメソッドの処理が終わった後からになるっぽく、その所為で -executeMethod の処理シーケンスの中では非同期的な処理を仕込んでも何も起きなかった、という感じっぽい。

対策

  • 関連する全ての非同期なコードを同期なコードに書き換えました。
  • 基本的には、CI 環境にインストールされている aws コマンドとか、 git コマンドとか、 hub コマンドとかを叩くだけなので、 System.Diagnostics.Process をゴリゴリ回せば OK ってコトで。

所感

  • いやー、罠だった。
  • でも、お陰で UniRx の MainThreadDispatcher とかを熟読できたので、良かったってコトにしておこう。

*1:そう思った根拠となる記事を見失ってしまいました…。