public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializerReader internalReader) { if (reader.TokenType == JsonToken.Null) { if (!ReflectionUtils.IsNullable(objectType)) { throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); } return(null); } if (objectType == null && existingValue != null) { objectType = existingValue.GetType(); } JsonContract contract = internalReader.GetContractSafe(objectType); UnityEngine.Object unityObject = null; if (!reader.MoveToContent()) { throw JsonSerializationException.Create(reader, "No JSON content found."); } if (reader.TokenType == JsonToken.Null) { return(null); } else if (reader.TokenType == JsonToken.StartObject) { string id; string unityGuid; Type resolvedObjectType = objectType; if (internalReader.Serializer.MetadataPropertyHandling == MetadataPropertyHandling.Ignore) { // don't look for metadata properties reader.ReadAndAssert(); id = null; unityGuid = null; } else if (internalReader.Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead) { JTokenReader tokenReader = reader as JTokenReader; if (tokenReader == null) { JToken t = JToken.ReadFrom(reader); tokenReader = (JTokenReader)t.CreateReader(); tokenReader.Culture = reader.Culture; tokenReader.DateFormatString = reader.DateFormatString; tokenReader.DateParseHandling = reader.DateParseHandling; tokenReader.DateTimeZoneHandling = reader.DateTimeZoneHandling; tokenReader.FloatParseHandling = reader.FloatParseHandling; tokenReader.SupportMultipleContent = reader.SupportMultipleContent; // start tokenReader.ReadAndAssert(); reader = tokenReader; } object newValue; if (internalReader.ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, null, null, null, existingValue, out newValue, out id, out unityGuid, out unityObject)) { if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid)) { if (SceneReferenceResolver.Current.Contains(unityGuid)) { SceneReferenceResolver.Current.Set(unityGuid, unityObject); } else { SceneReferenceResolver.Current.Add(unityGuid, unityObject); } } if (unityObject != null) { return(unityObject); } return(newValue); } } else { reader.ReadAndAssert(); object newValue; if (internalReader.ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, null, null, null, existingValue, out newValue, out id, out unityGuid, out unityObject)) { if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid)) { if (SceneReferenceResolver.Current.Contains(unityGuid)) { SceneReferenceResolver.Current.Set(unityGuid, unityObject); } else { SceneReferenceResolver.Current.Add(unityGuid, unityObject); } } if (unityObject != null) { return(unityObject); } return(newValue); } } if (internalReader.HasNoDefinedType(contract)) { return(internalReader.CreateJObject(reader)); } bool createdFromNonDefaultCreator = false; JsonObjectContract objectContract = (JsonObjectContract)contract; object targetObject; // check that if type name handling is being used that the existing value is compatible with the specified type if (existingValue != null && (resolvedObjectType == objectType || resolvedObjectType.IsAssignableFrom(existingValue.GetType()))) { targetObject = existingValue; } else if (unityObject != null) { targetObject = unityObject; } else { targetObject = Create(reader, internalReader, objectContract, id, unityGuid, objectType, out createdFromNonDefaultCreator); } if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid)) { if (SceneReferenceResolver.Current.Contains(unityGuid)) { SceneReferenceResolver.Current.Set(unityGuid, (UnityEngine.Object)targetObject); } else { SceneReferenceResolver.Current.Add(unityGuid, (UnityEngine.Object)targetObject); } } // don't populate if read from non-default creator because the object has already been read if (createdFromNonDefaultCreator) { return(targetObject); } internalReader.OnDeserializing(reader, contract, targetObject); bool referenceAdded = false; if (id != null && targetObject != null) { internalReader.AddReference(reader, id, targetObject); referenceAdded = true; } targetObject = Populate(contract, reader, objectType, targetObject, internalReader); if (id != null && targetObject != null && !referenceAdded) { internalReader.AddReference(reader, id, targetObject); } internalReader.OnDeserialized(reader, contract, targetObject); return(targetObject); } else { throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } }