Kyle Banks

Unity: Accessing Private and Protected Fields from the Inspector

Written by @kylewbanks on Jul 29, 2020.

Most everyone knows that publicly exposing your MonoBehaviour variables in Unity allows you to modify them in the Inspector window of the Unity editor. This is really helpful for tuning and adjusting parameters without having to modify code, and allows you to more easily reuse MonoBehaviour classes across objects where you may want different values. But how do you access private or protected properties?

For instance, you might have a Drive class that moves a vehicle around the scene, but you want different vehicles to have different speeds. You could simply make a public Speed variable and assign the various values to each vehicle from the inspector:

using UnityEngine;

public class Drive : MonoBehaviour
{
	public float Speed;
}

Now you can attach this script to your GameObjects and tune the Speed parameter for each.

Editing public variables in the Unity inspector

This is well and good but it means your variables remain public at runtime, meaning they’re both readable and writable from anywhere. There are a number of downsides to this, particularly as your project grows. It basically all boils down to reducing complexity, but here’s a slightly more detailed explanation of why you generally want to keep your private bits private: Why do we need private variables?

The good news is that it’s actually trivial to get non-public variables into the inspector using the SerializeField attribute. Here’s what the documentation has to say:

When Unity serializes your scripts, it only serializes public fields. If you also want Unity to serialize your private fields you can add the SerializeField attribute to those fields.

Perfect, that’s exactly what we want. Let’s add another field, this time a Vector3 direction, but set it to private while using the SerializeField attribute:

using UnityEngine;

public class Drive : MonoBehaviour 
{

    public float Speed;    
    
    [SerializeField] private Vector3 Direction;

}

Head over to the inspector and you’ll see it behaves exactly the same as a public field.

Private variable visible in the Unity inspector using the SerializeField attribute

Aside from adjusting parameters, another use case for accessing non-public fields in the inspector is for debugging. Rather than scattering Debug.Log statements throughout your code, visualizing private fields in the inspector would ease the debug process as you can actually see the value of your fields as they change in real time.

Bonus: Header Attribute

Just to avoid confusion between these debug parameters and those that are meant to be adjusted in the editor, I like to use the Header attribute to group fields:

using UnityEngine;

public class Drive : MonoBehaviour 
{

    [Header("Parameters")]
    [SerializeField] private float Speed;    
    [SerializeField] private Vector3 Direction;

    [Header("Debug Only")]
    [SerializeField] private bool Driving;
    [SerializeField] private float DriveTime;
    [SerializeField] private Vector3 Destination; 

}

These headers are then visible from the inspector in the Unity Editor, allowing for some nice organization.

Grouping parameters in the Unity inspector using the Header attribute

And that’s all there is to it! Now you can debug and adjust your private or protected properties from the Inspector window of the Unity editor, and keep all your fields organized.

Let me know if this post was helpful on Twitter @kylewbanks or down below!