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