Hi,
I’m having some trouble with the [SerializeReference] attribute. It seems that my objects are not stored correctly, whenever I reload a scene, I get lots of null pointer exceptions.
I have the following script attached to a couple of GameObjects in the scene (toy example obviously):
using System.Collections;
using UnityEngine;
using Classes;
[System.Serializable]
public class SceneObject : MonoBehaviour
{
[SerializeField] public ClassEnum classType;
[SerializeReference] public AbstractClass instance;
void Start()
{
Debug.Log(instance.doSomething());
}
}
There’s a custom editor for it that has a drop-down list for the 3 different types (A, B and C). Once chosen, an object of the corresponding type is instantiated.
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using Classes;
[CustomEditor(typeof(SceneObject))]
public class SceneObjectEditor : Editor
{
public override void OnInspectorGUI()
{
SceneObject sceneObj = (SceneObject)target;
ClassEnum newType = (ClassEnum)
EditorGUILayout.EnumPopup(
"Class Type",
sceneObj.classType);
if (newType != sceneObj.classType)
{
switch (newType)
{
case ClassEnum.A:
sceneObj.instance = new ClassA();
break;
case ClassEnum.B:
sceneObj.instance = new ClassB();
break;
case ClassEnum.C:
sceneObj.instance = new ClassC();
break;
}
sceneObj.classType = newType;
}
if (!Application.isPlaying && GUI.changed)
{
EditorUtility.SetDirty(target);
EditorSceneManager.MarkSceneDirty(sceneObj.gameObject.scene);
}
}
}
And here are the classes I’m trying to serialize:
namespace Classes
{
[System.Serializable]
public abstract class AbstractClass
{
public abstract string doSomething();
}
[System.Serializable]
public class ClassA : AbstractClass
{
public override string doSomething()
{
return "I am A";
}
}
[System.Serializable]
public class ClassB : AbstractClass
{
public override string doSomething()
{
return "I am B";
}
}
[System.Serializable]
public class ClassC : AbstractClass
{
public override string doSomething()
{
return "I am C";
}
}
[System.Serializable]
public enum ClassEnum
{
A,
B,
C
}
}
If I change the value with my drop down list and then hit play, I get all the correct messages. As soon as I reload the scene, I will get null pointers, until I use the inspector to select a different type again. What am I doing wrong?
The confusing part is, I have a different script where I serialize a list of polymorphic types and it works just fine. I cannot for the life of me figure out what’s different. Did something about SerializeReference change in the 0b6 update?