Variable set in inspector becomes null at runtime

In editor:
9850080--1418082--upload_2024-5-22_16-42-20.png

In playmode:
9850080--1418085--upload_2024-5-22_16-42-32.png

Context: Microgame Preview Default Sprite & Mg Ceelo are both set to asset files.

Things that don’t fix this:

  • Restarting Unity
  • Updating Unity
  • Restarting my PC

Look for any code that writes to it (assigns to it)… there’s an extremely-bad common pattern out there where a public field is ALSO then assigned to from GetComponent().

These variables are not touched by any code at all when entering play mode.

Tried tossing the Library folder?

unfortunately that didn’t work either :confused:

Are you sure?

If they are public change them from
public Sprite microgamePreviewDefaultSprite;
to
[SerializeField] private Sprite microgamePreviewDefaultSprite;
and see if the compiler complains. :wink:

Also check all uses of this sprite in your script. Perhaps you assign it somewhere? Consider whether it might assign null. Set a breakpoint and debug.

1 Like

This bug occurs even if I comment out the only line of code referencing it. Also I can’t set it to private because the I set the variables using the inspector asset picker.

Note: My screenshot is taken with the editor paused immediately upon entering play mode.

SerializeField exists to expose non-public fields to the Inspector. :wink:

Try creating an empty scene, put that component on it, add the same references and then enter playmode. If necessary comment out some code that doesn’t work in isolation.

Also post the code for the component in case there’s something one of us can spot.

2 Likes

That’s… not true. We have the [SerializeField] attribute to serialize non-public members. And it of course draws with the exact same drawer as public fields.

There’s no custom inspectors at work here?

2 Likes

no chances somethings being destroyed?

A destroyed object would show ‘Missing’ rather than ‘None’.

1 Like

Whenever you may have issues with a variable getting changed, you can always exchange them with a property that does additional logging when you read or write to it. The only thing that could not be detected would be Inspector or serialization system changes.

So if you have

public Sprite microgamePreviewDefaultSprite;

you can temporarily replace it by

[SerializeField]
[FormerlySerializedAs("microgamePreviewDefaultSprite")]
private Sprite m_MicrogamePreviewDefaultSprite;
public Sprite microgamePreviewDefaultSprite
{
    get {
        Debug.Log("Reading microgamePreviewDefaultSprite: " + m_MicrogamePreviewDefaultSprite, gameObject);
        return m_MicrogamePreviewDefaultSprite;
    }
    set {
        Debug.Log("Writing microgamePreviewDefaultSprite old value: " + m_MicrogamePreviewDefaultSprite + " new value: " + value, gameObject);
        m_MicrogamePreviewDefaultSprite = value;
    }
}

This will log any occation when the variable / property is set to a different value. The stack trace of the log tells you which method (chain) caused this change.

If this does NOT detect anything, you either have some dodgy CustomEditor that is messing with the fields or you use some serialization system (JsonUtility, …) or reflection code that is overwriting those values. We can’t really help you here any further. At the moment we don’t even know if we talk about a MonoBehaviour or ScriptableObject or if those fields are part of a custom serializable class instance. You have to do the debugging as we don’t have your code or project, so that’s all up to you.

2 Likes

And now the part where I feel silly! Yup, this helped me track the issue down. I’m definitely going to keep this snippet in mind!

2 Likes