Playボタン押した後のInitializeOnLoadは無視したい
Playボタンを押すと再ビルド・コンパイルされInitializeOnLoadが実行される。スクリプト更新時にInitializeOnLoadが実行されるのは良いがPlayボタン押した後は実行させない方法を考えてみた。
EditorApplication.playmodeStateChangedでイケるかと思いきやうまく行かなかったのでまず、InitializeOnLoadの動きを下のクラスを用意して調べてみた。
using UnityEngine; using UnityEditor; [InitializeOnLoad] public class InitOnLoad { static int couner = 0; static InitOnLoad() { ++couner; EditorApplication.playmodeStateChanged += ChangedPlaymodeState; EditorApplication.update += Update; Log(couner + " InitOnLoad!"); } static void ChangedPlaymodeState() { ++couner; EditorPrefs.SetBool("editor_InitOnLoad", EditorApplication.isPlayingOrWillChangePlaymode); Log(couner + " State Changed!"); } static void Update() { ++couner; Log(couner + " Update!"); EditorApplication.update -= Update; } static void Log(string called) { Debug.Log(called + " \n Application.isPlaying=" + Application.isPlaying + " \n EditorApplication.isPlaying=" + EditorApplication.isPlaying + " \n Application.isCompiling=" + EditorApplication.isCompiling + " \n Application.isPaused=" + EditorApplication.isPaused + " \n EditorApplication.isPlayingOrWillChangePlaymode=" + EditorApplication.isPlayingOrWillChangePlaymode + " \n editor_InitOnLoad=" + EditorPrefs.GetBool("editor_InitOnLoad", false) + " \n Time.timeSinceLevelLoad=" + Time.timeSinceLevelLoad + " \n EditorApplication.timeSinceStartup=" + EditorApplication.timeSinceStartup ); } }
①他スクリプト更新した時
1 InitOnLoad! Application.isPlaying=False EditorApplication.isPlaying=False Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=False editor_InitOnLoad=False Time.timeSinceLevelLoad=0 EditorApplication.timeSinceStartup=16947.9626049995 |
2 Update! Application.isPlaying=False EditorApplication.isPlaying=False Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=False editor_InitOnLoad=False Time.timeSinceLevelLoad=0 EditorApplication.timeSinceStartup=16948.164436996 |
プレイ中ではないので全てFalse。まぁ、期待通り。
②Playボタン押下(再生)した時
3 State Changed! Application.isPlaying=False EditorApplication.isPlaying=False Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=True editor_InitOnLoad=True Time.timeSinceLevelLoad=0 EditorApplication.timeSinceStartup=16972.6508870125 |
1 InitOnLoad! Application.isPlaying=False EditorApplication.isPlaying=False Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=False editor_InitOnLoad=True Time.timeSinceLevelLoad=0 EditorApplication.timeSinceStartup=16973.5056480169 |
2 State Changed! Application.isPlaying=True EditorApplication.isPlaying=True Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=True editor_InitOnLoad=True Time.timeSinceLevelLoad=0.02 EditorApplication.timeSinceStartup=16974.5213000178 |
3 Update! Application.isPlaying=True EditorApplication.isPlaying=True Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=True editor_InitOnLoad=True Time.timeSinceLevelLoad=0.02 EditorApplication.timeSinceStartup=16974.5486119986 |
課題の箇所。
「3 State Changed!」が純粋にボタンが押された時、コンパイル後にプレイモードになるので「isPlayingOrWillChangePlaymode」がTrueになっている。
コンパイルされるとリセットされ再度コンストラクタが呼ばれる。(counterも初期化されている。)この時はエディタ上ではまだプレイ中になっていない、isPlayingは全てFalse。
その後に「2 State Changed!」、ここからエディタはプレイ中と判断される。
結果
結果は、Unityの変数などからコンストラクタ内でPlayボタン押した後かどうかは判断できない。update内で判断させる。
もしくは、EditorPrefsにプレイボタンを押したかセットさせればコンストラクタ内で判別できる。
おまけ
③Playボタン押下(停止)した時
4 State Changed! Application.isPlaying=True EditorApplication.isPlaying=True Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=False editor_InitOnLoad=False Time.timeSinceLevelLoad=42.50671 EditorApplication.timeSinceStartup=17029.9978790283 |
5 State Changed! Application.isPlaying=False EditorApplication.isPlaying=False Application.isCompiling=False Application.isPaused=False EditorApplication.isPlayingOrWillChangePlaymode=False editor_InitOnLoad=False Time.timeSinceLevelLoad=0 EditorApplication.timeSinceStartup=17030.6096889973 |
なんで、こんな事したいと思ったかというのは、InitializeOnLoadで自動実行処理が増えていくとプレイボタン押した後にも実行されるのがウザくなってきたから。
スクリプトとか編集しないプランナーとかはそれで良いんだけど、エンジニアだとスクリプト編集後にEditorにフォーカスする時にもInitializeOnLoadが実行されるので無駄に実行されることになる。
早く動作確認したいときには便利な気がする。