It’s been a while since I last posted a blog. I was busy with a few things, I had a deadline to meet for my new game which is now in the closed testing phase and will be available to download next month.
Apart from this, I also have some good news to share, I am now a Unity Certified Associate Game Developer 🎉
Anyways, with that said, let’s start with today’s blog.
With this post we are starting a new blog series where we’ll learn techniques that make your development process bug resistant, systems that fail early and tell you what went wrong, instead of throwing errors at runtime.
🤔What does Fail Fast mean?
Fail fast means detecting problems during development or in the Editor rather than discovering them while the game is running.
The earlier something breaks, the easier it is to fix.
⚠️The problem with GetComponent()
While writing gameplay logic in C#, you must have used GetComponent().
It is used to get a reference to another component on the same GameObject.
But if you forget to add that required component…
💥 NullReferenceException
So, what if we could make sure that component is never missing?
🗝️RequireComponent
This is where RequireComponent comes into the picture.
RequireComponent is an attribute that automatically adds the required component when the script is attached to a GameObject.
You don’t have to remember to add it manually.
[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : MonoBehaviour
{
}
Now whenever this script is added, Unity will also add a Rigidbody.
📝Note:
This does not cache the reference. You still need to call GetComponent() in your script but now you are safe because the component will always exist.
🤔What about other types of data?
RequireComponent works for components.
But what about:
- integers
- floats
- strings
- optional references
- value validation?
This is where OnValidate() comes in.
🗝️OnValidate()
OnValidate() is an Editor-only method.
It is called when:
- values change in the Inspector
- the script is recompiled
- entering Play mode
- the scene loads
- It does not run in builds.
We can use it to:
- perform null checks
- clamp values
- auto-assign references
- validate scene-only usage
- keep serialized data in sync
RequireComponent is for mandatory components.
OnValidate is for data validation and smart auto-setup.
Example
private void OnValidate()
{
if (canvasGroup == null)
{
canvasGroup = GetComponent<CanvasGroup>();
if (canvasGroup == null)
{
canvasGroup = gameObject.AddComponent<CanvasGroup>();
Debug.Log($"Added missing CanvasGroup to {gameObject.name}");
}
}
if (masterVolume < -80f) masterVolume = -80f;
if (masterVolume > 0f) masterVolume = 0f;
if (uiElement == null)
{
Debug.LogWarning($"[Validation] {gameObject.name}: UI Element is not assigned!", gameObject);
}
if (sceneSpecificLight != null)
{
// Check if the object being validated is a Prefab or a Scene Instance
bool isPrefab = EditorUtility.IsPersistent(this);
bool isLightInScene = !EditorUtility.IsPersistent(sceneSpecificLight);
if (isPrefab && isLightInScene)
{
Debug.LogError($"[Validation] {gameObject.name}: You cannot assign a Scene object (Light) to a Prefab asset! Please clear this field.");
sceneSpecificLight = null; // Force clear to prevent broken references
}
}
if (actionButton != null && !actionButton.interactable)
{
Debug.Log($"{gameObject.name}: Action Button is currently set to Non-Interactable.");
}
}
💡Key Takeaway
Don’t wait for runtime errors to tell you something is wrong.
Using RequireComponent and OnValidate, you can detect problems in the Editor itself and make your scripts far more reliable. This is the first step towards a bug resistant development workflow.
Top comments (0)