Unity custom editor, values will not serialize

I’m aware this problem has been asked like 1000 times. As far as I can tell, though, my setup is fine, and I’ve done this before. I have the usual issue: I edit my object, but it will not keep those values when I reload the scene. Interestingly enough, it appears to sometimes keep the values when I go to play mode, which as I understood before should have meant it was working. Guess not.

Another super weird thing: when I am editing an object that’s in the scene view (selected from the hierarchy window), the editor shows up properly in the inspector and I can do whatever. But when I try to edit the prefab (selected from the project window), the inspector shows absolutely no properties, just the script name that I can tab open or closed (to no effect).

So here’s my (partial) code:

public class CritterView : MonoBehaviour
{
    [SerializeField]
    protected List<CritterVisualPart> visualParts;
    
    protected Animator animator;
    
    public void Start()
    {
        //WARNING - before this happens, you should have set the Random.seed to be what you wanted!
        
        if ( visualParts == null )
        {
            visualParts = new List<CritterVisualPart>();
        }
        
        PopulatePartsRandomly();
    }
    
    public List<CritterVisualPart> VisualParts
    {
        get
        {
            return visualParts;
        }
        set
        {
            visualParts = value;
        }
    }

[System.Serializable]
public class CritterVisualPart
{
    [SerializeField]
    protected string name;
    
    [SerializeField]
    protected string copiedPartName;
    
    [SerializeField]
    protected List<CritterVisualOption> options;

[System.Serializable]
public class CritterVisualOption
{
    public enum Type
    {
        Sprite = 0,
        Prefab,
        Count
    };
    
    [SerializeField]
    protected GameObject prefab;
    
    [SerializeField]
    protected Sprite sprite;
    
    [SerializeField]
    protected Type type;

And the editor:

[CustomEditor(typeof(CritterView))]
public class CritterViewEditor : Editor
{
    public override void OnInspectorGUI()
    {
        CritterView critterView = target as CritterView;
        
        List<CritterVisualPart> parts = GetNewParts( critterView );
        
        for ( int partIndex = 0; partIndex < parts.Count; partIndex++ )
        {
            ShowVisualPartGUI( parts, parts[ partIndex ] );
            
            GUILayout.Space( 16 );
        }
        
        critterView.VisualParts = parts;
        
        EditorUtility.SetDirty( critterView );
    }

Is it because I’m nesting serialized objects or something? As far as I know that should work.

Also, does anyone know where I can actually go look at the YAML that gets generated for the prefabs? Doesn’t appear to be in the meta file. Seems like that would be a good way to diagnose issues.

I fixed it! But I don’t even know how, exactly. I think my problems were stemming from two things:

First, I was using GetComponentsInChildren() to show parts of my UI. This would cause the behavior where in the prefab view you would see nothing. I fixed that part simply by calling GetComponentsInChildren( true ) instead, so that inactive (everything in the prefab view) could be found.

Second, I wasn’t using mark dirty at all, since it seemed to be working without it. In the code I posted above, I have it, since I had just tried to add it to get things going. Because of the first problem, above, though, it didn’t appear to be helping. When I cleared up the first one, the rest started to work. I think!

So, uh, for whoever reads this in the future: I think my advice would be to take things slow and test iteratively that stuff is actually saving (by closing and re-opening the scene) and that prefabs are working as well. I made the mistake of writing probably around 1000 lines across 5 classes for all this without testing that the saving was working. Make sure that’s part of your iterative testing so you can isolate and find the weak link early.