前提
- 今、お仕事で「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:そう思った根拠となる記事を見失ってしまいました…。