Reputation: 171
I'm using a custom Editor Script to display and adjust parameters of elements in a Reorderable List. But whenever I restart Unity and click the GameObject holding the script, these parameters are reseted (like shown in the picture at the end of the post). When I deactivate the Custom Editor Script, everything works as it should, so the problem might be in this script.
This is the Story class using the custom Editor script:
[System.Serializable]
public class Story : MonoBehaviour
{
public List<Chapter> ChapterList;
}
and the Editor Script, using a Reorderable List:
[CustomEditor(typeof(Story))]
public class StoryEditor : Editor
{
private Story story;
private ReorderableList reorderableList;
void OnEnable()
{
story = (Story) target;
if (story.ChapterList == null)
story.ChapterList = new System.Collections.Generic.List<Chapter>();
if (reorderableList == null)
reorderableList =
new ReorderableList(
story.ChapterList,
typeof(Chapter),
true, true, true, true);
reorderableList.drawElementCallback += DrawElement;
}
private void DrawElement(Rect rect, int index, bool active, bool focused)
{
Chapter c = story.ChapterList[index];
EditorGUI.BeginChangeCheck();
c.ID = index+1;
EditorGUI.IntField(new Rect(rect.x, rect.y, 20, rect.height-1), c.ID);
c.Title = EditorGUI.TextField(new Rect(rect.x + 21, rect.y, rect.width - 79, rect.height-1), c.Title);
c.Hide = EditorGUI.Toggle(new Rect(rect.x + rect.width - 56, rect.y, 17, rect.height-1), c.Hide);
if (GUI.Button(
new Rect(
rect.x + rect.width - 40, rect.y, 40, rect.height-1), "Edit"))
Select(index);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(target);
}
}
I googled the problem, but the solutions I found mentioned to use [System.Serializable] and EditorUtility.SetDirty(target);, which I'm using both. I assume I'm missusing something in the "DrawElement" method, but I can't figure out what it is.
Upper part: Before Restarting, Lower Part: After Restarting Unity.
Upvotes: 1
Views: 2180
Reputation: 171
There were several problems I've encountered while working on this issue. First: The if statement in the Editors OnEnable()
method is true everytime you reselect the object holding the Story script. This seems to be because of the way Editor Scripts are working. I think they're reinstantiated whenever the user reselects the object. Therefore I moved the new List<Chapter>();
part to the Story class and implemented a Getter functionality.
private List<Chapter> chapterList;
public List<Chapter> ChapterList
{
get
{
if (chapterList == null)
chapterList = new List<Chapter>();
return chapterList;
}
}
The next issue were the private variables. While public variables are always serializable, private values will not be serialized (allthough the class is marked as [System.Serializable]
, which I thought would solve this problem). To make private variables Serializeable, they have to be marked as a [SerializeField]
.
[SerializeField]
private List<Chapter> chapterList;
public List<Chapter> ChapterList
{
get
{
if (chapterList == null)
chapterList = new List<Chapter>();
return chapterList;
}
}
After I add [SerializeField]
to every private variable in my classes, the problem was gone.
Upvotes: 1