Need a hand using array.Length in a C# editor script

Hey everybody, I’ve been getting hounded by a nullreference error while using array.Length in a C# editor script

This is the editor script (With unnecessary script lines removed)

using UnityEngine;
using UnityEditor;
using System.Collections;
    [CustomEditor(typeof(SentryTurretAI))]
    public class SentryTurretAIEditor : Editor {
    	int sections;
    	bool[] showSentryPart;
    	string[] aimFromObjects;
    	
    	public override void OnInspectorGUI () {
    		EditorGUIUtility.LookLikeControls();
    		SentryTurretAI sentryTurretAI = (SentryTurretAI) target as SentryTurretAI;
    		sections = sentryTurretAI.sentryObjects.Length;
    }

And this is the actual script affected:

using UnityEngine;
using System.Collections;

[System.Serializable]
public class trackObject {
        //These are variables in 'sentryObjects'
	public Transform rotatingObject;
	public float trackSpeed;
	public Vector3 up;
	public bool local;
	public bool x;
	public bool y;
	public bool z;
}

    [System.Serializable]
    public class SentryTurretAI : MonoBehaviour {
    	public trackObject[] sentryObjects;
        //Removed clutter
        }

The above posted is what I’ve narrowed down as the problem, I’ve been working at it for a while and have had no prevail! To the best of my knowledge, this should be working but it gives this error (ignore line reference):

NullReferenceException: Object reference not set to an instance of an object
SentryTurretAIEditor.OnInspectorGUI () (at Assets/Editor/SentryTurretAIEditor.cs:14)
UnityEditor.InspectorWindow.DrawEditors (Boolean isRepaintEvent, UnityEditor.Editor editors, Boolean eyeDropperDirty)
UnityEditor.InspectorWindow.OnGUI ()
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture)

Any help would be absolutely amazing!

Thanks,

-AJ

Well, can't see something wrong. Maybe your target casting cause the problem since you double cast. Keep in mind when using the as-operator when the cast fails it returns null. Are you sure that your sentryTurretAI variable is not null ? Also you should use only one cast. I do the cast usually in OnEnable and hold the reference in a public variable so i don't need to cast it every inspector update.

1 Answer

1

It seems that your sentryObjects is still null. Which it is, because you haven’t defined sentryObject yet. Where is the line where you say: sentryObjects = new trackObject[5]?

Arrays need to be created, just like any other object. The problem with an array is that you have to specify the length at creation time.

You're right, arrays needs to be created and also the contained objects needs to be created, but If you edit the property in the inspector the array AND the contained objects gets created by Unity. If you call sentryObjects = new trackObject[5] somewhere in your script you will delete all contained objects since you recreate the array.

Indeed, if they are in the inspector, even with no elements, you still get an array (with Length==0), not an undefined array.

You'd get compile-time errors if any variables didn't exist. Throw in if(sentryTurretAI.sentryObjects!=null) in front of everything. Or, to be extra cool, on null create a length 1 array (above,) and create and set-up sentry #0: trackObject TT = new trackObject(); sentryTurretAI.sentryObjects[0] = TT; TT.range=12; TT.type=1; ...