/// <summary> /// Will create copies of everything in the object's reference graph using the following rules: anything /// Unity can serialize (see Unity documentation on serialization for a complete list), but also /// ScriptableObjects that are either direct references, or otherwise contained in a serializable type /// belonging to the previous category. So as of this writing, a field containing a scriptable object adorned /// with [SerializeField] or public, contained in an array or list, or a field in a serializable custom class /// will be copied. Examples where a scriptable object will not be copied: as keys or values in a dictionary, /// in a non-public field not marked with [SerializeField], in a non-serializable class. /// </summary> public static T CopyDeep <T>(this T obj) where T : ScriptableObject { obj = obj.CopyShallow(); var serializedObject = new SerializedObject(obj); var iterator = serializedObject.GetIterator(); iterator.Next(true); while (iterator.NextVisible(true)) { if (iterator.propertyType == SerializedPropertyType.ObjectReference) { ScriptableObject so = iterator.objectReferenceValue as ScriptableObject; if (so != null) { so = so.CopyDeep(); iterator.objectReferenceValue = so; } } } serializedObject.ApplyModifiedProperties(); return((T)serializedObject.targetObject); }