概要
最後のビルドの動作を見たいときに、出力フォルダを開くのがめんどくさかったり、そもそも出力フォルダがどれだったか分からなくなるので、エディタ拡張で最後のビルドを実行する機能を作りました。
その過程で躓いたところも備忘録的にまとめます。
さくっと機能を使いたい方は、UnityPackageManagerで以下URLを「Add package from git URL...」してください。
https://github.com/udonba/Unity-RunLastBuild.git?path=Packages/RunLastBuild
機能
- ビルドすると自動でその出力パスを記録する
- エディタのメニューから最後のビルドを実行できる(Run Last Build)
- 実行ファイル(.exe)なら実行し、それ以外なら出力フォルダを開く
ビルドする際は通常の操作と同じで、特別な操作は必要ありません。
通常のビルド処理に相乗りするようにしています。
解説
以下の組み合わせで実装します。
- ビルド結果(ビルドした実行ファイルのパス)を取得する
- パスをエディタに保持する
- エディタから外部ファイルを実行する
ビルド結果を取得する
ビルド結果を取得するには、2つの方法があります。
① ビルド処理自体をBuildPipeline.BuildPlayer
で自作し、その結果を受け取る
② IPostprocessBuildWithReport
インターフェースを実装し、ビルド後のコールバックで結果を取得する
今回は後者②の方法でやりました。
IPostprocessBuildWithReportでビルド結果を取得する
このインターフェースで実装するOnPostprocessBuild
は、引数のBuildReport型にビルド結果が格納されています。IPostprocessBuildWithReport
インターフェースを実装すればビルド後に呼び出されます。
この中身を見れば、ビルド結果を使っていろいろできます。
今回は実行ファイルのパスだけ分かれば十分なので、report.summary.outputPath
を使います。
void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report)
{
// 出力パスを保存
SaveOutputPath(report.summary.outputPath);
}
パスをエディタに保存する
ビルドの出力パスの取得はできました。次はこのパス文字列を、エディタに保持してもらいます。
ScriptableObjectを作成してこれに書き込みます。今回はstring型1個だけのシンプルなものを作成しました。
エディタに保持するだけなら、EditorPrefsを使う方法もあり、こっちの方が実装も楽です。しかし、EditorPrefsはプロジェクトを横断して設定を保持します。(参考記事)
今回はプロジェクトごとに別個にビルドを保持させたかったので、ScriptableObjectを採用しました。
エディタから外部ファイルを実行する
Application.OpenURL
を使用します。
保存されたビルド出力のパスをScriptableObjectから読み込み、これに渡してあげることで、表題の機能が実装できます。
(うろ覚えですがmac環境だとProcess.Start
を使うのがめんどくさかった記憶があるので、Application.OpenURL
を使っています。)
躓いたところ
report.summary.resultがビルド成否と一致しないバグ
ビルドが成功したときだけ処理したかったのですが、BuildReport
にちゃんと結果が入ってませんでした。どうやらそういうバグが残っているようです。
IPostprocessBuildWithRepor
がそもそもビルドが成功したときしかコールバックされなかったので、今回は影響はありませんでした。
参考:[BUILDREPORT] REPORT IN IPOSTPROCESSBUILDWITHREPORT PROVIDES INCORRECT INFORMATION
Packages下にあるScriptableObjectを読み込む際は、Assets下とパスの形態が異なる
↑ エディタのProjectビューではPackages/RunLastBuild/Editor/LastBuildInfo.asset
にファイルがあるように見えますが、このパスをAssetDatabase.LoadAssetAtPath
メソッドに渡しても読み込めません。
Packages下のファイルをLoadAssetAtPathするには、Packages/com.udonba.runlastbuild/Editor/LastBuildInfo.asset
のようなパスを渡してあげる必要があります。
参考:Using AssetDatabase.LoadAssetAtPath inside packages.