Unitip 3: OnValidate

In MonoBehaviour scripts, there are many functions that get called when certain Unity Engine events occur such as Start() and Update(). However, there is a suite of many more MonoBehavior methods that are very helpful including: OnEnable(), OnTriggerEnter(), Awake(), etc.

A lesser known function is OnValidate() which is an editor only function that called when the script is loaded or a value changes in its inspector.

This is helpful for automatically setting other inspector values based on another.

Setting inspector information based on a slider value.

[SerializeField] [Range(0,10)] private float number;
[SerializeField] private int numberInt;
[SerializeField] private string numberStr;
[SerializeField] private bool isEven;

string[] numberWords = new string[] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

private void OnValidate()
{
    numberInt = Mathf.FloorToInt(number);
    isEven = numberInt % 2 == 0;
    numberStr = numberWords[numberInt];
}

This is a great way to set some values using the inspector without having to write a custom editor script! The particular example may not seem extremely useful, but another good use is to get all children of a certain type without having to drag and drop a bunch.

Getting all children using OnValidate

[SerializeField] private Transform[] children;

private void OnValidate()
{
    children = new Transform[transform.childCount];
    for (int i = 0; i < transform.childCount; i++)
    {
        Transform child = transform.GetChild(i);
        children[i] = child;
    }
}

You can see from the code how you could easily check the child object for a particular component, tag, or layer and add it to your list!

There’s an obvious drawback in that you have to make a change to the inspector in order for the code to run. This is not only a little inconvenient, but easy to miss if you make changes to your scene that require the inspector to be updated. So you still have to remember to either reload the script by reloading the scene, or modify something in the inspector to force the code to run. Still, this can be a really useful item to keep in your back pocket.

Other features you could implement with OnValidate:

  • Select a color from the list to apply to model so you don’t have to adjust the material.

  • Setting a health bar or clock value in the inspector to see its effect on the UI element.

  • Update sprites based on prefab. See Jason Weimann’s video

I would not recommend using this method for initializing your component with other non-children game objects. You could end up in situations where you need a value from that outside object and it has not yet set because it has not yet calculated it. Sticking to Awake and Start are best practices for that, but keep OnValidate in your back pocket!