Edit static variable with custom eidtor

I’m trying to find a way to edit a static variable through the Inspector. I tried to write a custom editor:

    private Slider _slider;
    private static Slider _slider;

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        EditorGUI.BeginChangeCheck();
        // FIXME: static variable doesn't save its state.
        _slider = EditorGUILayout.ObjectField("Progress slider", _slider, typeof(Slider), true) as Slider;
        if (EditorGUI.EndChangeCheck())
        {
            IntermediateScene.slider = _slider;
            serializedObject.ApplyModifiedProperties();
            EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
        }
    }
    }

but for some the slider variable doesn’t save its value. Whenever a new level is loaded or Unity is restarted, it goes back to null.

I’m not sure how you’d force it to save this, or where it would save the data if you could. (I would think if you managed to make it save, it would save a copy of the reference on every instance of the script, which would could a plethora of sync-related issues on its own).

This sort of thing is solved much more cleanly and easily (no editor scripting needed) with a singleton pattern. You make your slider a local reference, then make a static reference to that instance which assigns itself in Awake(), and can use SomeClass.instance._slider. Would that be workable for your use case?

In addition to the “no place to save it” issue, there’s the issue that references to GameObjects or Components can only be saved within the same scene; since a static variable is not related to any specific scene, the only “safe” value you could ever save to it would be null.

I already have excessive amount of singletons. I need this variable to be static because it’s used by a static method. As I understand there’s no way one would be able to treat a static variable as a normal one and assign a value to it via the Inspector panel. I already solved my problem by initializing it from Awake:

    private void Awake()
    {
        if (slider == null)
        {
            slider = GetComponentInChildren<Slider>();
        }
    }

Thank you for help.

Are you absolutely sure you want that method to be static? The use of GetComponentInChildren() strongly implies that the data you are using is instance-specific.

If you have multiple copies of this class in your scene, you’ll still only have one “slider” variable, which means whichever one Awakes last will “win” and write its child component to the variable, while the sliders in the other instances will be forgotten.

If you have zero copies of this class in your scene, the static method can still be called, but Awake will never run.

Unless this class is, itself, a singleton, it’s hard to see how this could possibly be safe.

1 Like

Yeah, the more I see of your code the more sure I am that a singleton is the right answer.

There are times to be cautious about having too many singletons in your code, but UI code is almost always happy as a singleton. And if you have a static reference to an instance, like you have in your solution - guess what, that is going to have exactly the same drawbacks as a singleton might have.

There is only one instance of this class. Probably you’re right, I may have to consider making this object a singleton.