Custom Inspector resets ObjectField-data when play the scene, but Default Inspector doesn't

So far I’ve searched out some solution about this issue:
1,Make the Object Serializable.
2,Use the SetDirty method.

But I’m still confused because the Default Inspector can set any GameObject with a single line in Script :“public GameObject xxx;”

Any difference between the ObjectField in Default Inspector and Custom Inspector?

How I can make a Custom Inspect Object field that can set any GameObject on it without reset when playing?

1 Like

Can you post your code? (Please read Using code tags properly first.) Sounds like it’s not serializing.

yeah, I’ve picked up the key part of the code, the ObjectField “noteProto” is reset when playing, and the noteProto is just a prefab Object with nothing special.

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(NoteSpawner))]
public class NoteSpawnerEditor : Editor
{
    NoteSpawner spawner;

    GameObject noteProto;


    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnEnable()
    {
        spawner = (NoteSpawner)target;
    }

    public override void OnInspectorGUI()
    {
        noteProto = (GameObject)EditorGUILayout.ObjectField("Note proto", noteProto, typeof(GameObject), false);
        if (noteProto != null)
            spawner.noteProto = noteProto;
    }
}

Try changing line 32 of the code above to:

noteProto =(GameObject)EditorGUILayout.ObjectField("Note proto", spawner.noteProto, typeof(GameObject), false);

Better yet, I would consider getting rid of “GameObject noteProto;” (line 11) and use this:

spawner.noteProto =(GameObject)EditorGUILayout.ObjectField("Note proto", spawner.noteProto, typeof(GameObject), false);

This will let you assign null to spawner.noteProto, for example if you want to clear the field.

The original problem is that the editor script’s noteProto starts null. You could always set “noteProto = spawner.noteProto” in OnEnable(), but it’s probably better to omit it entirely.

1 Like

Yeah it works, and i’ve learned sth form this issue. Thank you TonyLi

Happy to help!

Sorry to bump this, but I’m having the same problem and I use the direct variable:

    private void OnGUI( )
    {
        minSize = new Vector2( 300, 150 );

        _MakeSpaces( 3 );
  
        _bake_brush = EditorGUILayout.Toggle( "Bake brush", _bake_brush );
        _bake_fog = EditorGUILayout.Toggle( "Bake fog", _bake_fog );
        _auto_update = EditorGUILayout.Toggle( "auro update", _auto_update);
        TextureBaker.fogBakerMaterial = (Material)EditorGUILayout.ObjectField( "FogBaker material", TextureBaker.fogBakerMaterial, typeof( Material ), false );

...

Why TextureBaker.fogBakerMaterial goes to none when building the project or pressing “play” ?
The other 3 toggle variable keeps state, so only this material objct is reseted.

When Unity switches to play mode, it serializes your window, destroys it, and creates a new window with the serialized data. Only public fields, and private fields marked [SerializeField], are serialized. Everything else is reset to their default values. In addition, scene objects will be different in play mode because Unity serializes the scene and creates it new in play mode. So if your editor window has a reference to something in the scene, that reference will no longer be valid in play mode.

See Unity Serialization for more info.

that material is a material that exists in my project, outside. And it+s a public static material. So given your comments it should work.
anyway I tried putting Serialiable and SerializeField, but it doesn’t work.

Can you post more code? What’s TextureBaker? Could another part of the script be assigning a value to TextureBaker.forBakerMaterial that is no longer valid? Also make sure to read through the Unity Serialization link above. It probably contains an answer to your question. Or check this post and keep a reference to the material’s instance ID.

Hello I have the same problema (apparently), but I use UI buider and UI toolkit, this is a bit of my code

var grassField = root.Q<ObjectField>("GrassField");
        grassField.objectType = typeof(RuleTile);
        sizeField.RegisterCallback<ChangeEvent<RuleTile>>(v => {
            comp.grass = v.newValue;
        });

I don’t know how to solve this from ui bulder, when starting playmode the values of the cmaps are reset, I don’t know if it’s an error in how I’m building the object or it’s a RuleTile error that can’t be used (I don’t think so), I’m using the unity tilemap2d package ruletile.