Hey CDF thank you so much for the update it’s awesome!!
to get back on the GetItem function. Is there a way to access the variables from the list in another non-editor script? Because I can get it to work, but only in editor scripts where I can put ‘using Malee.Editor’.
I’ll take a look at your code. In more detail, I want to access the variables in my list from another (non editor script) and use those values. I don’t want to modify the values, but just read-only. So for example in a script attached to a gameobject, there is a variable that has the value of whatever is inputted in the list from the editor script before running the game.
Nice project! Just thought I’d let you know there is a very similar project by someone else here: Bitbucket which also works well and maybe you’ll find it interesting to see how someone else solves the same problem.
hey CDF, me again. Is there a way to change the default values of variables in the list. So that when the user attaches the script to an object, and adds a list element, some variables already have default values. (without using a prefab), thanks! And also I noticed, when I enter values in a list element, and then I add a new element, it copies the variable values of the previous list, is there a way to modify this?
That’s just how Unity’s serialization system works. Unless your objects derive from MonoBehaviour or ScriptableObject those items will initialize to their base default values: float = 0, bool = false etc.
When duplicating an element, Unity will copy the serialized properties into the new object automatically.
You can see this happening on a regular array. Right click the element in the Editor and Duplicate it, notice the values are copied.
You can listen to the “onAddCallback” on the List to override the “add” button functionality.
In order to initialize a complete list on Startup you would do something similar. Make a private “initialized” bool on your class. Check the value on the CustomEditor “OnInspectorGUI” method, if false, make it true. Use list.AddItem() as above and initialize the default values. Something like:
class MyClass {
[SerializeField]
private bool initialized;
public MyItem[] items;
[System.Serializable]
public class MyItem {
public bool myBool;
public float myFloat;
}
}
class MyClassEditor : Editor {
void OnEnable() {
list = new ReorderableList(serializedObject.FindProperty("items"));
list.onAddCallback += AddItemToList;
}
public override OnInspectorGUI() {
serializedObject.Update();
if (!serializedObject.FindProperty("initialized").boolValue) {
serializedObject.FindProperty("initialized").boolValue = true;
InitializeItems();
}
serializedObject.ApplyModifiedProperties();
}
void AddItemToList(ReorderableList list) {
InitializeItem(list.AddItem());
}
private void InitializeItems() {
for (int i = 0; i < 10; i++) {
InitializeItem(list.AddItem());
}
}
private void InitializeItem(SerializedProperty item) {
item.FindPropertyRelative("myBool").boolValue = true;
item.FindPropertyRelative("myFloat").floatValue = 1;
}
}
I don’t have a callback for Duplicate yet though. I’m pretty busy now, if you need it, check "
HandleContextClick" and “HandleMultipleContextClick” functions. You should be able to hook up a callback in there with the right data
Also worth mentioning is you could skip the initialization through the list by directly modifying the array. You’ll still need an “initialized” bool. This way, you won’t generate an Undo/Redo on the items.
Thanks! I have one last (I hope) question though. I want to draw some variables outside of list in the inspector window. This is the code for List.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Malee;
public class List : MonoBehaviour
{
public float x;
public List<RotationTimelineData> RotationTimeline; //Define a list.
And this is the code in ListEditor.cs
public override void OnInspectorGUI()
{
DrawDefaultInspector();
serializedObject.Update();
RotationTimeline.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
This draws the variable I want and the list, but also the list in the form of an array:
Use the “drawElementCallback” to draw the property and its children. You may want to use the “getElementHeightCallback” to return a different height for each element if you’re changing how properties are shown.
void OnEnable() {
list = new ReorderableList(serializedObject.FindProperty("MyList"));
list.drawElementCallback += DrawElement;
list.getElementHeightCallback += GetElementHeight;
}
void DrawElement(Rect rect, SerializedProperty element, GUIContent label, bool selected, bool focused) {
if (DoorPro.VisualizeHinge == false) {
switch (element.name) {
case "HingeType":
case "HingeColor":
//don't draw this element if VisualizeHinge is false and the element is either "HingeType" or "HingeColor"
return;
}
}
//default element drawing
EditorGUI.PropertyField(rect, element, label, true);
}
float GetElementHeight(SerializedProperty element) {
if (DoorPro.VisualizeHinge == false) {
switch (element.name) {
case "HingeType":
case "HingeColor":
//element won't contribute to the height of the list when VisualizeHinge is false and the element is either "HingeType" or "HingeColor"
return 0;
}
}
//default element height
return EditorGUI.GetPropertyHeight(element, null, true);
}
I may add a “getListHeightCallback” with which you can process the entire lists height instead of per element
Alright, this way I can change whether or not variables are present outside of the list, based on variables inside the list, but then how would it work to make variables inside of the list ‘appear’ and ‘dissapear’ ? So I have variables inside the ListData class that shows up in the list, but then I would like to remove it based on an enum variable in that ListData class.