Objects in Custom Editor Resetting on Play
I'm trying to have a list of steps shown in the custom editor and then updating the serialized Object with some values. Whenever I press play the StepRestriction.referenceStep and StepRestriction.stepIndex are reset to the first item in the steps list and 0. I've looked on previous forums and the general response is to add serializedObject.Update() and serializedObject.ApplyModifiedProperties(), but I have both of these. I'm lost on why they keep resetting.
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TutorialSystem
{
...
public class StepRestriction : MonoBehaviour
{
[SerializeField]
RestrictionType restrictionType;
[SerializeField]
TutorialManager tutorialManager;
[SerializeField]
TutorialStep referenceStep;
[SerializeField]
public int stepIndex;
[SerializeField]
internal List<RestrictionPair> restrictions = new List<RestrictionPair>();
...
}
#if UNITY_EDITOR
[CustomEditor(typeof(StepRestriction))]
public class StepRestrictionInspector : Editor
{
SerializedProperty p_restrictionType;
SerializedProperty p_tutorialManager;
SerializedProperty p_stepIndex;
SerializedProperty p_onStep;
SerializedProperty p_referenceStep;
int selectedStepIndex;
private void OnEnable()
{
p_restrictionType = serializedObject.FindProperty("restrictionType");
p_tutorialManager = serializedObject.FindProperty("tutorialManager");
p_stepIndex = serializedObject.FindProperty("stepIndex");
p_onStep = serializedObject.FindProperty("onStep");
p_referenceStep = serializedObject.FindProperty("referenceStep");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
...
EditorGUILayout.PropertyField(p_tutorialManager);
ShowSteps();
ShowRestrictions();
serializedObject.ApplyModifiedProperties();
}
...
private void ShowSteps()
{
TutorialManager manager =
(TutorialManager)p_tutorialManager.objectReferenceValue;
if (manager == null) return;
TutorialStep[] steps = manager.GetSteps();
//create the array for the step names
string[] stepStrings = new string[steps.Length];
for (int i = 0; i < steps.Length; i++)
{
stepStrings[i] = steps[i].name;
}
//set the step from the popup
selectedStepIndex = EditorGUILayout.Popup(new GUIContent("Step"),
selectedStepIndex, stepStrings);
p_stepIndex.intValue = selectedStepIndex;
p_referenceStep.objectReferenceInstanceIDValue =
steps[selectedStepIndex].GetInstanceID();
}
}
#endif
}
Answer by fleity · May 10, 2021 at 08:02 PM
it is a bit a wild guess in the dark but I don't see you writing back to p_stepIndex.value or drawing it a property field which would do the same under the hood. Additionally it might be necessary to explizitly make TutorialStep serializable in its own class, but the int should work that way.
Tutorialstep inherits from GameObject so it is serializable. And according to my understanding p_stepIndex.intValue is being set on line 77 so it is supposed to be updating.
ah sorry I was a bit code blind already yesterday. What works for me is reading the selectedIndex from the serializedProperty back first. Disregard the GameObject Array, all you really need to add is selectedStepIndex = p_stepIndex.intValue;
private void ShowSteps()
{
selectedStepIndex = p_stepIndex.intValue;
GameObject[] steps = new GameObject[p_referenceSteps.arraySize];
for (int i = 0; i < steps.Length; i++)
{
steps[i] = p_referenceSteps.GetArrayElementAtIndex(i).objectReferenceValue as GameObject;
}
//create the array for the step names
string[] stepStrings = new string[steps.Length];
for (int i = 0; i < steps.Length; i++)
{
stepStrings[i] = steps[i].name;
}
//set the step from the popup
selectedStepIndex = EditorGUILayout.Popup(new GUIContent("Step"),
selectedStepIndex, stepStrings);
p_stepIndex.intValue = selectedStepIndex;
}