On Validate Method

Where the Reset Method only gets called once when the component is first added, Unity will call OnValidate much more often:

  • When the component is first added or the Reset function is used from its context menu (same as Reset).
  • When the component is loaded, such as when opening a scene, editing a prefab, or after you modify a script and Unity recompiles it.
  • When the component is modified in the Inspector.

So we can use it to simply get the required component if one wasn't already assigned:

using UnityEngine;

public sealed class OnValidateMethodExample : MonoBehaviour
{
    [SerializeField] private Rigidbody _Rigidbody;

    private void OnValidate()
    {
        if (_Rigidbody == null)
            TryGetComponent(out _Rigidbody);
    }

    private void FixedUpdate()
    {
        _Rigidbody.AddForce(Vector3.up * 10);
    }
}

Advantages

  • All the same advantages of the Reset Method, which are:
    • Fastest runtime performance - Unity deserializing the reference to set the field is faster than a script calling GetComponent on startup and the cost of calling it in Edit Mode doesn't actually matter.
    • The Inspector shows what other components the OnValidateMethodExample depends on and which one is actually being used.
    • The other components can be anywhere. The script isn't hard-coded with the assumption that the Rigidbody will be attached to the same GameObject.
    • It will automatically find the required Rigidbody (if there is one) when you first add the OnValidateMethodExample component.
  • If you add or rename a serialized field after you have already added the script to an object, the OnValidate method will get called again.

Disadvantages

Summary Description Solution
Verbose This approach uses more code than any other. Extension Methods can help reduce the length without losing the advantages of this approach.
Only runs on loaded objects If you add or rename a serialized field after you have already added the script to an object in a different scene that you don't currently have open, the OnValidate method will not get called on that object unless you go and actually open that scene and re-save it. Using a [FormerlySerializedAs attribute can avoid losing assigned values when you rename a field, but otherwise this can only really be avoided by the Get Component, Get Component Cached, and Require Component approaches which always perform their search at runtime.