Please indicate in the Hierarchy if a GameObject contains unassigned variables

Nothing worse than going to test your code only to be blue balled by a NullReferenceException. Diligence only getting you so far, and contributing unnecessary friction to your workflow.

Since Unity is essentially an over-featured GUI ref injector. We should expect its core service to be its best. As with all big projects, we/they must of gone blind to how big of an oversight this is.

Where in the case its not feasible, at least make it more noticeable in the inspector.

Unity got me back into development, so I owe it my honesty.
thank you!

2 Likes

In the meantime you can create a editor tool for it.

4 Likes

I made a simple method, that performs the check.

GameObject[] objects = GameObject.FindObjectsOfType<GameObject>();
foreach (GameObject obj in objects)
{
  Component[] comps = obj.GetComponents(typeof(MonoBehaviour));

  foreach (Component comp in comps)
  {
    FieldInfo[] fields = comp.GetType().GetFields();
    foreach (FieldInfo field in fields)
    {
      object value = field.GetValue(comp);
      if (value == null || value.Equals(null))
      {
        Debug.Log(obj.name + ": " + field.Name);
      }
    }
  }
}

There are a LOT of references on components which are optional though. I can’t imagine wading through all the false positives.

5 Likes

I may be doing it a brute force way, but if my code is expecting that a value in the inspector is already set, I check for a valid value, usually in Start. If there is no value, I log it to the console. In some cases, I might stick in an empty game object or other default value to keep later code from crashing while I’m working.

Some sort of marker on the hierarchy would be nice, though, just to help when wiring things up in the first place.

3 Likes

I made a small change to my code to now only get MonoBehaviour components. Which took care of all of the false positives in my current project.

.OnValidate is a better place for those checks, as it won’t be called in builds, saving some precious performance on loading scripts.

4 Likes

This only checks in current scene. You can also check all prefabs doing

    [MenuItem("MDA Digital/Misc/Output prefabs with unassgined members")]
    public static void OutputPrefabsWithUnassignedMembers()
    {
        var unassigned =
            AssetDatabase.FindAssets("t:Prefab")
                .Select(guid => AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(guid)))
                .Select(go => new { go, unassigned = go?.GetComponentsInChildren<MonoBehaviour>()?.SelectMany(mono => mono?
                        .GetType()
                        .GetFields()
                        .Where(f => (f.IsPublic || f.GetCustomAttributes(typeof(SerializeField), true).Any()) && f.GetValue(mono) == null))})
                .Where(info => info.unassigned != null && info.unassigned.Any())
                .ToList();

        foreach (var info in unassigned)
                Debug.LogWarning($"Prefab: {info.go.name} has these unnasigned members: {string.Join("; ", info.unassigned.Select(u => u.Name))}");
    }
1 Like

I use assertions in the Start method to detect when things that shouldn’t be null are. You should use conditional methods to do debugging checks like that in all your code, it’ll save you a lot of headaches down the line. Code behaving funny? -define:smile:EBUG

Odin Inspector has an attribute for this.

https://sirenix.net/odininspector/documentation/sirenix/odininspector/requiredattribute

4458145--409138--upload_2019-4-22_18-19-44.png

1 Like

Thank you. I used that once in a tutorial to check number values or something, but I hadn’t even thought about using it for value existence. I will have to start doing that.