Instruct Unity to serialize a field as a reference.
When Unity serializes an object, it serializes all fields as value types, unless the field type derives from [UnityEngine.Object].
By default, polymorphic fields are not supported and reference based topologies, like graphs, cannot be expressed natively.
It is recommended to derive the field type from ScriptableObject since this usually results in the best performance.
However, if using ScriptableObjects adds unacceptable complexity, decorating the field with a [SerializeReference] instructs Unity to serialize the field 'by reference' instead of 'by value'.
Notes:
- The field type must not be of a type that specializes UnityEngine.Object.
- The field type can be abstract.
- The field type can be an interface.
- Generic Lists and array fields decorated with [SerializeReference] apply the attribute to the elements of the list/array not the list/array instance itself.
- Referenced values cannot be shared between UnityEngine.Object instances. For example, two MonoBehaviours cannot share an object that is serialized by reference. Use ScriptableObjects instead to share data.
- Field value can be null.
- Field value cannot be a specific specialization of a generic type(inflated type).
- The type of the dynamic instance/object assigned to the field must be of a [Serializable] type.
- The types 'System.Object', 'List<System.Object>' or 'System.Object[]' are also supported for the field type.
using System; using System.Collections.Generic; using UnityEngine;
public interface IShape {}
[Serializable] public class Cube : IShape { public Vector3 size; }
[Serializable] public class Thing { public int weight; }
[ExecuteInEditMode] public class BuildingBlocks : MonoBehaviour { [SerializeReference] public List<IShape> inventory;
[SerializeReference] public System.Object bin;
[SerializeReference] public List<System.Object> bins;
void OnEnable() { if (inventory == null) { inventory = new List<IShape>() { new Cube() {size = new Vector3(1.0f, 1.0f, 1.0f)} }; Debug.Log("Created list"); } else Debug.Log("Read list");
if (bins == null) { // This is supported, the 'bins' serialized field is declared as holding a collection type. bins = new List<System.Object>() { new Cube(), new Thing() }; }
if (bin == null) { // !! DO NOT USE !! // Although, this is syntaxically correct, it is NOT supported as a valid serialization construct because the 'bin' serialized field is declared as holding a single reference type. bin = new List<System.Object>() { new Cube() }; } } }