public void RefreshLoDReferences()
 {
     foreach (FieldInfo field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
     {
         object[] attributes = field.GetCustomAttributes(typeof(LoadOnDemand), true);
         if (attributes.Length == 1)
         {
             LoadOnDemand     attribute = (LoadOnDemand)attributes[0];
             LoadOnDemandInfo lodInfo   = (LoadOnDemandInfo)field.GetValue(this);
             if (lodInfo != null && lodInfo.EditorGUID != null)
             {
                 string path = UnityEditor.AssetDatabase.GUIDToAssetPath(lodInfo.EditorGUID);
                 if (path == null)
                 {
                     Debug.LogWarning(string.Concat("[Scriptable Object Suite] ", name, " - Asset with guid ", lodInfo.EditorGUID, " referenced for ", attribute.FieldName, " does not exist anymore. Removing reference"));
                     lodInfo.EditorGUID   = null;
                     lodInfo.ResourcePath = null;
                 }
                 else
                 {
                     string previousPath = lodInfo.ResourcePath;
                     lodInfo.ResourcePath = AssetToResourcePath(path);
                     if (previousPath != lodInfo.ResourcePath)
                     {
                         Debug.LogWarning(string.Concat("[Scriptable Object Suite] ", name, " - Updated reference path for ", attribute.FieldName, " from ", previousPath, " to ", lodInfo.ResourcePath));
                     }
                 }
             }
         }
     }
 }
        public void OnSave()
        {
            foreach (FieldInfo field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                object[] attributes = field.GetCustomAttributes(typeof(LoadOnDemand), true);
                if (attributes.Length == 1)
                {
                    LoadOnDemand attribute   = (LoadOnDemand)attributes[0];
                    FieldInfo    linkedField = GetType().GetField(attribute.FieldName);

                    object value = linkedField.GetValue(this);
                    Object valueAsUnityObject = (Object)value;
                    if (value != null)
                    {
                        string           assetPath    = UnityEditor.AssetDatabase.GetAssetPath(valueAsUnityObject);
                        string           assetGuid    = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
                        string           resourcePath = AssetToResourcePath(assetPath);
                        LoadOnDemandInfo lodInfo      = new LoadOnDemandInfo(assetGuid, resourcePath);
                        field.SetValue(this, lodInfo);
                    }
                    else
                    {
                        field.SetValue(this, null);
                    }
                }
            }
        }
        /***************************
        * Core overridable methods *
        ***************************/
        protected virtual void DrawEditor(ObjectType target)
        {
            Dictionary <string, FieldInfo> lodFields = new Dictionary <string, FieldInfo>();

            foreach (FieldInfo field in typeof(ObjectType).GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
            {
                object[] attributes = field.GetCustomAttributes(typeof(LoadOnDemand), true);
                if (attributes.Length == 1)
                {
                    LoadOnDemand lodAttribute = (LoadOnDemand)attributes[0];
                    lodFields.Add(lodAttribute.FieldName, field);
                }
            }

            SerializedObject   targetSerialized = new SerializedObject(target);
            SerializedProperty nextProperty;

            FieldInfo[] fields = typeof(ObjectType).GetFields(BindingFlags.Instance | BindingFlags.Public);
            for (int i = 0; i < fields.Length; i++)
            {
                EditorGUILayout.BeginHorizontal();
                if (fields[i].Name != "FileName")
                {
                    nextProperty = targetSerialized.FindProperty(fields[i].Name);
                    try
                    {
                        EditorGUILayout.PropertyField(nextProperty, true);
                    }
                    catch (System.Exception e)
                    {
                        if (e.GetType() != typeof(ExitGUIException))
                        {
                            Object newValue = EditorGUILayout.ObjectField(fields[i].Name, (Object)fields[i].GetValue(target), fields[i].FieldType, false);

                            fields[i].SetValue(target, newValue);
                        }
                    }
                }
                if (lodFields.ContainsKey(fields[i].Name))
                {
                    EditorGUILayout.LabelField("Load on demand", EditorStyles.boldLabel, GUILayout.Width(115));
                    EditorGUILayout.EndHorizontal();
                    object fieldVal = lodFields[fields[i].Name].GetValue(target);
                    if (fieldVal != null)
                    {
                        LoadOnDemandInfo lodInfo = (LoadOnDemandInfo)fieldVal;
                        if (lodInfo.ResourcePath != null && lodInfo.ResourcePath.StartsWith("Assets/"))
                        {
                            EditorGUILayout.HelpBox("This attribute is a Load on Demand field that requires either an object in a Resource folder or another Scriptable Object", MessageType.Error);
                        }
                    }
                }
                else
                {
                    EditorGUILayout.EndHorizontal();
                }
            }
            targetSerialized.ApplyModifiedProperties();
        }
 public void Unload(string fieldName = null)
 {
     foreach (FieldInfo field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
     {
         object[] attributes = field.GetCustomAttributes(typeof(LoadOnDemand), true);
         if (attributes.Length == 1)
         {
             LoadOnDemand attribute          = (LoadOnDemand)attributes[0];
             string       attributeFieldName = attribute.FieldName;
             if (fieldName == null || attributeFieldName == fieldName)
             {
                 FieldInfo linkedField = GetType().GetField(attributeFieldName);
                 linkedField.SetValue(this, null);
             }
         }
     }
 }
 public void Load(string fieldName = null, bool async = false)
 {
     foreach (FieldInfo field in GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
     {
         object[] attributes = field.GetCustomAttributes(typeof(LoadOnDemand), true);
         if (attributes.Length == 1)
         {
             LoadOnDemand attribute          = (LoadOnDemand)attributes[0];
             string       attributeFieldName = attribute.FieldName;
             if (fieldName == null || attributeFieldName == fieldName)
             {
                 FieldInfo        linkedField = GetType().GetField(attributeFieldName);
                 LoadOnDemandInfo fieldValue  = (LoadOnDemandInfo)field.GetValue(this);
                 if (fieldValue != null)
                 {
                     if (async)
                     {
                         if (typeof(Sprite) == linkedField.FieldType)
                         {
                             linkedField.SetValue(this, Resources.LoadAsync <Sprite>(fieldValue.ResourcePath));
                         }
                         else
                         {
                             linkedField.SetValue(this, Resources.LoadAsync(fieldValue.ResourcePath));
                         }
                     }
                     else
                     {
                         if (typeof(Sprite) == linkedField.FieldType)
                         {
                             linkedField.SetValue(this, Resources.Load <Sprite>(fieldValue.ResourcePath));
                         }
                         else
                         {
                             linkedField.SetValue(this, Resources.Load(fieldValue.ResourcePath));
                         }
                     }
                 }
             }
         }
     }
 }