The OnValidate Method approach on its own requires more code than others, but with a simple Extension Method it can actually become one of the shortest.
Consider the following extension method:
public static partial class Extensions
{
public static void GetComponent<T>(this GameObject gameObject, ref T component)
where T : class
{
if (component == null)
component = gameObject.GetComponent<T>();
}
}
Having that class in your project would allow the OnValidate Method approach to look like this:
using UnityEngine;
public sealed class ExtensionMethodExample : MonoBehaviour
{
[SerializeField] private Rigidbody _Rigidbody;
private void OnValidate()
{
// Replace this:
if (_Rigidbody == null)
TryGetComponent(out _Rigidbody);
// With this:
gameObject.GetComponent(ref _Rigidbody);
}
private void FixedUpdate()
{
_Rigidbody.AddForce(Vector3.up * 10);
}
}
That gets the code length down to about the same as the Get Component Cached or Reset Method approaches without losing any of the advantages of the OnValidate Method approach.
Searching
The fact that the Reset Method and OnValidate Method are only run in the Unity Editor opens the possibility for your extension methods to search a bit more broadly since their performance won't affect the player experience once your game is actually built. For example, an extension method could search on the same GameObject
first, but if it doesn't find the component there it could search the parents and children as well until it finds one:
public static partial class Extensions
{
public static void GetComponentInParentOrChildren<T>(this GameObject gameObject, ref T component)
where T : class
{
if (component != null)
return;
component = gameObject.GetComponentInParent<T>();
if (component != null)
return;
component = gameObject.GetComponentInChildren<T>();
}
}
Advantages
- All the same advantages of the OnValidate 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
ExtensionMethodExample
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 sameGameObject
. - It will automatically find the required
Rigidbody
(if there is one) when you first add theExtensionMethodExample
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.
- Fastest runtime performance - Unity deserializing the reference to set the field is faster than a script calling
- It will still automatically find the required
Rigidbody
if it's on a parent or child object.
Disadvantages
- Searching across multiple objects does have the potential danger of it finding the wrong thing if something else happens to have that component.
- This can usually be fixed by manually assigning the component you want in the Inspector, but it does mean you now need to pay a bit more attention to the component it picks.