Access an Array of class inside another Array of class? (EditorGUILayout)
Hey guys, I'm not usually asking others about these kind of stuff. I'm just too frustrated to get this done. In fact, This is my first time asking the community. Btw, I'm trying to make a layout for my scriptableobject but i can't access the grandchildren with EditorGUILayout. Everything works fine at first when i am not using an array of class inside another array of class. I know I am making some very stupid logic here but i'm doing this because i'm puzzled on customizing array of class's properties with SerializedProperty.
Here's the Class Objects Script:
//MyScriptableObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
public class CreateQuestList{
[MenuItem("Assets/Create/MyScriptableObject")]
public static void instance(){
MyScriptableObject _instance = ScriptableObject.CreateInstance<MyScriptableObject> ();
ProjectWindowUtil.CreateAsset (_instance, "MyScriptableObject.asset");
}
}
#endif
public class MyScriptableObject : ScriptableObject {
public List<child> children;
public void AddChildren(){
children.Add (new child ());
}
public void AddGrandChildren(int ChildrenIndex){
children [ChildrenIndex].grandChildren.Add (new Grandchild ());
}
}
[System.Serializable]
public class child{
public List<Grandchild> grandChildren;
}
[System.Serializable]
public class Grandchild{
public string str;
}
Here's the Editor Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(MyScriptableObject))]
public class MyScriptableObjectEditor : Editor {
public override void OnInspectorGUI(){
MyScriptableObject so = (MyScriptableObject)target;
for (int i = 0; i < so.children.Count; i++) {
EditorGUILayout.LabelField ("Children "+i);
Rect ElementBox = (Rect)EditorGUILayout.BeginVertical ("box");
for (int j = 0; j < so.children [i].grandChildren.Count; j++) { //ERROR
so.children [i].grandChildren [j].str = EditorGUILayout.TextField ("GrandChildren str "+j, so.children [i].grandChildren [j].str);
}
EditorGUILayout.Space ();
if (GUILayout.Button ("add new grandchildren")) {
so.AddGrandChildren (i);
}
EditorGUILayout.EndVertical ();
EditorGUILayout.Space ();
}
EditorGUILayout.Space ();
if (GUILayout.Button ("add new childrenn")) {
so.AddChildren ();
}
}
}
Here's what my Scriptable Object Looks like:
And Here's what it's supposed to be looked like:
The problem is on my loop, the console says Object reference not set to an instance of an object. That makes editor script snap and will not allow me to add new children.
Answer by DashW · Feb 04, 2017 at 06:58 AM
So, the only issue I can see is that you're not instantiating either of your lists.
Unlike C++ where arrays can be constructed on the stack or as part of an enclosing object without being 'newed', all objects and arrays in C# are handled by reference, therefore they always need to be 'newed'.
The lines should be:
public List<child> children = new List<child>();
public List<Grandchild> grandChildren = new List<Grandchild>();
With these changes, your code works for me.