(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

エディタを実行していない時にOnValidateでDestory【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 5.3.4f1 Personal


はじめに

以下のように、エディタを実行していない時にOnValidateでDestoryしようとするとエラーが出ます。

private void OnValidate (){
  Destroy (gameObject);
}

f:id:kan_kikuchi:20160623132947p:plain

Destroy may not be called from edit mode! Use DestroyImmediate instead.
Also think twice if you really want to destroy something in edit mode.
Since this will destroy objects permanently.


どうやらエディタを実行していない時にはDestroyではなく、DestroyImmediateを使えとの事。

ですが、素直に使おうとするとエラーが出ます。

private void OnValidate (){
  DestroyImmediate (gameObject);
}

f:id:kan_kikuchi:20160623133321p:plain

Destroying GameObjects immediately is not permitted during physics trigger/contact,
animation event callbacks or OnValidate. You must use Destroy instead.


どうやらOnValidateからDestroyImmediateは使えず、Destoryを使えとの事。

ですが、素直に使おうとするとエラーが(以下ループ


delayCall

上記の通り、

エディタ実行中ではない時のOnValidateからはDestroyもDestroyImmediateも使えません。


ではどうするかといえば、EditorApplication.delayCallを使います。

すべてのインスペクターが更新された後に1度だけ呼び出されるデリゲート


これを使えばエディタ実行中でなくとも、ちょっと間をあけてメソッドの実行が可能になります。

具体的には以下のような感じ。デリゲートやらイベントについてはこちらをどうぞ。

//ラムダ式の匿名メソッドを使うパターン
private void OnValidate(){
    EditorApplication.delayCall += () => DestroyImmediate(gameObject);
}
//通常のメソッドを使うパターン
private void OnValidate(){
    EditorApplication.delayCall +=DestroySelf;
}

private void DestroySelf(){
  EditorApplication.delayCall -= DestroySelf;
  DestroyImmediate(gameObject);
} 


なお、EditorApplicationを使うにはusing UnityEditor; が必要になります。


これでOnValidateでDestoryできるようになりました!めでたしめでたし(:3っ)∋〜


参考