青空の月

Unity, C#, アプリ開発関連について。

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が実行されるので無駄に実行されることになる。

早く動作確認したいときには便利な気がする。