예제 #1
0
    private bool IsLateAttributeField(object obj, FieldInfo field, out FieldInfo targetField, bool performChecks)
    {
        targetField = null;

        LateAttribute lazyAttribute = Attribute.GetCustomAttribute(field, typeof(LateAttribute)) as LateAttribute;

        if (lazyAttribute == null)
        {
            return(false);
        }

        string targetIdField = lazyAttribute.TargetIdField ?? (field.Name + (field.FieldType.IsArray ? "Ids" : "Id"));

        targetField = obj.GetType().GetField(targetIdField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        if (targetField == null)
        {
            throw new UnityException(FormatTargetFieldErrorMessage("does not exist", obj, field, lazyAttribute.TargetIdField));
        }

        if (performChecks)
        {
            if (ScanningUtils.IsSerializableArray(field.FieldType))
            {
                if (!typeof(UnityEngine.Object).IsAssignableFrom(ScanningUtils.GetSerializableArrayType(field.FieldType)))
                {
                    throw new UnityException(FormatLateFieldErrorMessage("is not an UnityEngine.Object assignable array", obj, field.Name));
                }

                if (ScanningUtils.GetSerializableArrayType(targetField.FieldType) != typeof(string))
                {
                    throw new UnityException(FormatTargetFieldErrorMessage("is not a string array", obj, field, targetIdField));
                }
            }
            else
            {
                if (!typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType))
                {
                    throw new UnityException(FormatLateFieldErrorMessage("is not an UnityEngine.Object assignable", obj, field.Name));
                }

                if (targetField.FieldType != typeof(string))
                {
                    throw new UnityException(FormatTargetFieldErrorMessage("is not a string", obj, field, targetIdField));
                }
            }

            if (!targetField.IsPublic && Attribute.GetCustomAttribute(targetField, typeof(SerializeField)) == null)
            {
                throw new UnityException(FormatTargetFieldErrorMessage("is not public or have [SerializeField] attribute", obj, field, lazyAttribute.TargetIdField));
            }

            if (targetField.IsPublic && Attribute.GetCustomAttribute(targetField, typeof(HideInInspector)) == null)
            {
                Debug.LogWarning(FormatTargetFieldErrorMessage("is public but don't have the [HideInInspector] attribute, " +
                                                               "this field is not meant to be editable by users", obj, field, lazyAttribute.TargetIdField));
            }
        }

        return(true);
    }
예제 #2
0
    private bool RetargetLateAttributeField(object obj, FieldInfo field)
    {
        FieldInfo targetField;

        if (IsLateAttributeField(obj, field, out targetField, false))
        {
            if (ScanningUtils.IsSerializableArray(field.FieldType))
            {
                IList idsArray = (IList)targetField.GetValue(obj);

                UnityEngine.Object[] referencesArray = (UnityEngine.Object[])Activator.CreateInstance(field.FieldType, new object[] { idsArray.Count });
                for (int i = 0; i < idsArray.Count; i++)
                {
                    referencesArray[i] = AssetId.FromId((string)idsArray[i], ScanningUtils.GetSerializableArrayType(field.FieldType));
                }

                field.SetValue(obj, (object)referencesArray);

                                #if !DEBUG_KEEP_IDS
                targetField.SetValue(obj, null);
                                #endif
            }
            else
            {
#if !KEEP_BROKEN_LINKS
                string val = (string)targetField.GetValue(obj);
                field.SetValue(obj, (object)AssetId.FromId(val, field.FieldType));
#endif

                                #if !DEBUG_KEEP_IDS
                targetField.SetValue(obj, null);
                                #endif
            }

            return(true);
        }

        return(false);
    }