Unityでシーンビルド時の処理を記述できる IProcessSceneWithReport.OnProccessScene の使い方をまとめます。
Unity2021.3.0f
はじめに
IProcessSceneWithReport.OnProcessScene
を使用すると、シーンがビルドされる時の処理を記述することができます。
これにより、例えばシーンに配置したデバッグ用の GameObject を、リリースビルドの時にだけ削除することができそうです。
本記事ではこれの使い方についてまとめます。
なお参考までに関連する機能として、エディタでだけ存在する GameObject を作成できる EditorOnly タグがあります。
このタグをつけたGameObjectは、プレイヤービルドでは常に削除されます。
またもう一つ関連する機能として、ビルドの前後処理を挟めるIPreprocessBuildWithReport
やIPostprocessBuildWithReport
もあります。
プレイヤービルド時に特定のGameObjectを削除する
それではこの機能を使って、プレイヤービルドの際にシーン上の特定の GameObject を削除するスクリプトを書いてみます。
以下はシーンのルートにあるGameObjectに、Debugという名前のものがあったらそれを削除するスクリプトです。
using UnityEditor; using UnityEditor.Build; using UnityEditor.Build.Reporting; using UnityEngine; using UnityEngine.SceneManagement; public sealed class Example : IProcessSceneWithReport { public int callbackOrder => 0; public void OnProcessScene(Scene scene, BuildReport report) { // OnProcessScene はエディタで PlayMode に入る時にも呼ばれる // この場合には EditorApplication.isPlaying がtrueになるのでこれで判定する // マニュアルにはエディタ実行の際にはreport引数がnullになるという説明がされているが、 // これだとシーンをアセットバンドルビルドした時にも当てはまってしまうので以下の判定の方がよさげ if (EditorApplication.isPlaying) return; Debug.Log("OnProcessScene: " + scene); // シーンのルートにDebugというGameObjectがあったら削除する var sceneRootObjects = scene.GetRootGameObjects(); foreach (var rootObject in sceneRootObjects) if (rootObject.name == "Debug") Object.DestroyImmediate(rootObject.gameObject); } }
コメントに書いていますが、IProcessSceneWithReport.OnProcessScene
はプレイヤービルド時の他に、エディタでシーンを再生した時にも呼ばれます。
この時には EditorApplication.isPlaying
が true
になるため、この引数を見て判定し、ビルド時にだけ処理されるようにしています。
なおコメントにも書いていますが、report
引数が null
かどうかで判定するのはアセットバンドルのことを考えると控えた方が良さそうです。
動作確認
さて最後にこのスクリプトをEditorフォルダに入れて動作を確認していきます。
Debug という名前の GameObject を配置したシーンを適当に作成します。
今回は Debug の子として Sphereを 配置しました。
次にこれをビルドします。
まず比較のために、上記のスクリプトがプロジェクト内にない状態でビルドします。
当然ですが、Sphere が存在していることを確認できました。
次に上記のスクリプトを入れた状態でビルドし直します。
Sphere が消えている子を確認できました。
シーンをアセットバンドルした時にも呼ばれることを確認
また、このシーンをアセットバンドルにする可能性を考えると、アセットバンドルビルド時にもこの処理が正常に行われる必要があります。
これを確認するために、当該シーンを Addressables のエントリとして追加します。
この状態で Addressables のビルドを行うと、以下のログが出力され、正常に処理が行われていることを確認できます。
ちなみに当然ですが一度シーンをビルドしてから、ProcessSceneWithReport
を作成し差分ビルドをした場合には、シーンに変更が加わっていない限りビルドされないので、ProcessSceneWithReport
の処理は行われません。
この場合には Clean Build をしてからビルドし直す必要があります。