けいごのなんとか

Unityユーザーとしてのブログ。ギリギリ路線走ってます。

MonoBehaviour.OnValidate()

この情報はUnity Documentation Tabsでも閲覧することが出来ます

Unity Documentation Tabsで閲覧する場合のURLはこちら(EN)またはこちら(JP)です


エディタースクリプト(CustomEditorPropertyDrawer)いらずでインスペクター上で値を変更した時のコールバックとして大活躍するOnValidate

ある特定のパラメータが変更された時、それに関係するパラメータも変更を行いたい時に便利

あまりピンとこない人向けに簡単にサンプル書いてみた。

Playerのレベルが変わるごとにHPなども変化するサンプル

using UnityEngine;

public class Example : MonoBehaviour
{
    public Level level;
    public Player player;
   
    void OnValidate()
    {
        player = new Player(level);
    }
}

public enum Level
{
    Easy = 1,
    Normal = 2,
    Hard = 3,
}

[System.Serializable]
public class Player
{
    public Player(Level level)
    {
        name += string.Format(" ( {0} )", level);
        hp *= (int)level;
        pow *= (int)level;
        speed *= (int)level;
    }

    public string name = "Level";
    public int hp = 100;
    public int pow = 50;
    public int speed = 20;
}

OnValidateの中でObjectの削除

どうやらOnValidate実行時ではObjectの削除が行えないみたい。

Destroyで消そうとすると

Destroy may not be called from edit mode! Use DestroyImmediate instead.

DestroyImmediateで消そうとすると

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

仕方ないのでEditorApplication.delayCallで削除のタイミングをずらして対処

void OnValidate()
{
    EditorApplication.delayCall += () => DestroyImmediate(gameObject);
}