- Home /
Custom Inspector fields reset when focus is lost
I am attempting to create a custom editor for one of my scripts, and part of the functionality is that I have a ClassObjects that require a reference name to a datum from a component on a GameObject. this is done in such a way that I only need the datum in order to access what I need from the component.
in the ClassObjectEditor I am storing the reference object for the datum. I can place the GameObject reference, and obtain the datum in the component, but when I lose focus on the GameObject holding the ClassObject, and then return focus the Inspector reads that the GameObject reference is null(none), but when I look at the Debug Inspector it says the datum is still there.
steps to recreate:
create a ClassA
in ClassA hold a variable (example string str)
create an editor for ClassA (ClassAEditor)
in ClassAEditor hold a GameObject
when a GameObject is placed in a ObjectField get the GameObject.name
place the GameObject.name into ClassA.str
lose focus on the GameObject holding ClassA then return focus (the GameObject field should read null(none)
switch to Debug Inspector
is this intended behavior?
Answer by gardian06 · Apr 15, 2013 at 02:54 PM
it would seem that the member variables of a custom inspector are shared across all instances of that script to be inspected, so what this means is if I have a ScriptX, and then I have a ScriptXEditor and ScriptX is applied to 5 different objects. there are 5 instances of ScriptX, but there is still only 1 instance of ScriptXEditor; therefore whenever focus is lost on an object with an instance of the ScriptX all of the member variables of ScriptXEditor will be reset to their default values.
this seems to be intended behavior for what seems to be as the values, and references held by a custom inspector are only really meant to be used in the editor and by minimizing the amount of thing that needs to be stored in memory while in the editor decreases performance demands from O(n) to O(1) per member per script instance and considering that the editor is already more demanding then say a release build.
also it seems to be expected that for most things that will be stored as members in a custom inspector should either be calculated, or only for setup purposes. if a value to be viewable in the custom inspector can not be calculated it must be stored in the script the editor script references.
//DummyScript
using UnityEngine;
using System.Collections;
public class DummyScript : MonoBehaviour {
public int maintain = 5;
}
//DummyScriptEditor
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(DummyScript))]
public class DummyScriptEditor : Editor{
DummyScript dummy;
public int dummyMember = 10;
public void OnEnable(){
dummy = (DummyScript)target;
}
public override void OnInspectorGUI(){
dummy.maintain = EditorGUILayout.IntField("maintain", dummy.maintain);
dummyMember = EditorGUILayout.IntField("Editor Member", dummyMember);
if(GUILayout.Button("Apply member to maintain")){
dummy.maintain = dummyMember;
}
if(GUILayout.Button("Apply maintain to member")){
dummyMember = dummy.maintain;
}
// all other editor code goes before this
if(GUI.changed){ EditorUtility.SetDirty(dummy);}
}
}
to test
create a scene, and place any number of empty GameObjects in the scene, and attach the DummyScript to each.
if you modify maintain when focus is lost it the new value will stay.
if you modify Editor Member when focus is lost the value will reset to default
Answer by zoeyschlemper · Nov 03, 2020 at 06:12 PM
One thing that no one talks about is the core function of an Inspector. Inspectors just display data contained in the asset being inspected. So each time the Inspector gains focus and calls OnInspectorGUI, you have to grab a reference to the instance of the object being inspected and fill in your custom fields with data from it. Otherwise, even if you successfully edit the asset through your Inspector, the default values will always be shown and NOT the current values on the asset.
Then, when the editing session finishes, you do what gardian06 says, which is to tell Unity that the asset has changed since last time, and that data needs to persist after the session ends.
These two things are the core functionality of a custom Inspector.