【Unity】ExecuteInEditModeと関連コンポーネントの破棄対応について

ExecuteInEditModeを付けるとエディタ上でもスクリプトが稼動するようになり、独自のメッシュ生成などのエディタ拡張がしやすくなる。
関連コンポーネントがない場合や、残ったままでもいい場合は問題ないが、
HideInInspectorで隠蔽しておきつつ適切に削除したい時などに問題が起きる。

何も対策せずにOnDestroyの中で関連コンポーネントを削除するようにすると、
Hierarchyからゲームオブジェクトを削除した時と、エディタ上でPlayボタンを押した直後にエラーが表示される。

エラー内容:

Destroying object multiple times. Don’t use DestroyImmediate on the same object in OnDisable or OnDestroy.

解決策

MonoBehaviourのOnDestroyでの対応

プレイ中は特に問題ないため、プレイ中にのみ破棄する。

コード例:

void OnDestroy()
{
  if( Application.isPlaying )
  {
    // 関連コンポーネントの削除
    DestroySubComponents();
  }
}

Inspector拡張でMonoBehaviourの削除を検知

InspectorのRemove Conponentで破棄された場合に関連コンポーネントが残ってしまうので、
エディタ拡張で検知して、関連コンポーネントの削除を呼び出す。

コード例:

using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(HogeBehaviour))]
public class HogeBehaviourInspector : Editor
{
  void OnDestroy() 
  {
    if( !target ) 
    {
      HogeBehaviour hoge = (HogeBehaviour)target;
      // 関連コンポーネントの削除
      hoge.DestroySubComponents();
    }
  }
}

Unityのアセット販売中!

ステートマシンの状態遷移やパラメータはエディタで編集でき、
ゲームロジックに依存するステートの挙動はスクリプトで記述可能なエディタ拡張。

詳細はこちら

RPGツクールVXやWOLF RPGエディターのオートタイルに準拠したエディタ拡張。

詳細はこちら

オススメ!