はじめに
- エディタ拡張で、ビルド前に動的にコードを生成したくて調べたら、インターフェイスを継承してコールバックを使うという記事がいくつか見つかりました。
- 前処理は
IPreprocessBuild.OnPreprocessBuild
で、後処理はIPostprocessBuild.OnPostprocessBuild
が紹介されています。 - ところが、書いてみたら
obsolete
で警告されました。
- 前処理は
- そこから色々調べた結果です。
環境
- Unity 2020.3.x
今時の方法
リンク先の「公式スクリプトリファレンス」にもコード例があります。
以降の例は、ほぼ公式のままなので、リンク先をご覧いただいた方が分かり易いかも知れません。
ビルド前処理
- ビルド開始前に呼ばれます。
- インターフェイスを継承したクラスを用意して、コールバックを受けます。
-
IPreprocessBuildWithReport.OnPreprocessBuild
コールバック (公式スクリプトリファレンス)
-
- ビルド前には、
OnEnable ()
が先に呼ばれるので注意する必要があります。
コード例
- 方針
- 別クラスで定義されている変数を表示するだけのシーンを用意します。
- エディタ拡張で、ビルド直前に、クラスが定義されたファイルを動的に生成します。
- 生成されたコードによって、変数は現在日時で初期化されます。
- 生成されているファイルの初期化子と、実行で表示された日時が一致すれば成功です。
- このやり方で、実行時には取得できない(あるいは取得の面倒な)
PlayerSettings
の要素などをコードに取り込むことが可能です。
Assets/Editor/PreBuild.cs
using System;
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
public class PreBuild : IPreprocessBuildWithReport {
public int callbackOrder => 0; // ビルド前処理の中での処理優先順位 (0で最高)
public void OnPreprocessBuild (BuildReport report) {
Debug.Log ($"IPreprocessBuildWithReport.OnPreprocessBuild for {report.summary.platform} at {report.summary.outputPath}");
var ScriptPathPrefKey = $"{PlayerSettings.companyName}/{PlayerSettings.productName}/ScriptPath";
var AssetPath = EditorPrefs.GetString (ScriptPathPrefKey, "Assets/");
File.WriteAllText (Path.Combine (AssetPath, "Data.cs"), // 要するに、Assets/Data.csに以下を書き出す
$@"public class Data {{
public static readonly string BuildDateTime = ""{DateTime.Now}""; // コード生成時の日時
}}");
AssetDatabase.Refresh (); // アセットDBの更新
}
}
ビルド中処理
- シーンがビルドされる毎に呼ばれるようです。
- インターフェイスを継承したクラスを用意して、コールバックを受けます。
-
IProcessSceneWithReport.OnProcessScene
コールバック (公式スクリプトリファレンス)
-
コード例
Assets/Editor/SceneBuilded.cs
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
public class SceneBuilded : IProcessSceneWithReport {
public int callbackOrder => 0;
public void OnProcessScene (UnityEngine.SceneManagement.Scene scene, BuildReport report) {
Debug.Log ($"IProcessSceneWithReport.OnProcessScene {scene.name} as {report.name}");
}
}
ビルド後処理
- ビルド完了後に呼ばれます。
- インターフェイスを継承したクラスを用意して、コールバックを受けます。
-
IPostprocessBuildWithReport.OnProcessScene
コールバック (公式スクリプトリファレンス)
-
コード例
Assets/Editor/PostBuild.cs
public class PostBuild : IPostprocessBuildWithReport {
public int callbackOrder => 0;
public void OnPostprocessBuild (BuildReport report) {
Debug.Log ($"OnPostprocessBuild for {report.summary.platform} at {report.summary.outputPath}");
}
}