Ejemplo n.º 1
0
 void SetToPrototype()
 {
     System.Type type = _aso.GetType();
     string[]    availablePrototypes = AssetDatabase.FindAssets(string.Format("t:{0}", type));
     if (availablePrototypes.Length > 0)
     {
         //Get the actual names of each object
         List <AdvancedScriptableObject> assets = new List <AdvancedScriptableObject>();
         for (int i = 0; i < availablePrototypes.Length; i++)
         {
             string path = AssetDatabase.GUIDToAssetPath(availablePrototypes[i]);
             AdvancedScriptableObject obj = AssetDatabase.LoadAssetAtPath(path, typeof(AdvancedScriptableObject)) as AdvancedScriptableObject;
             //Prevent parenting to self
             assets.Add(obj);
         }
         GenericMenu menu = new GenericMenu();
         for (int i = 0; i < availablePrototypes.Length; i++)
         {
             GUIContent gc = new GUIContent(assets[i].name);
             menu.AddItem(gc, false, OnSelectedPrototype, availablePrototypes[i]);
         }
         menu.ShowAsContext();
     }
     else
     {
         Debug.LogWarning("No suitable prototypes found");
     }
 }
    public static void Delete(AdvancedScriptableObject deleteFrom, AdvancedScriptableObject objProperty)
    {
        //Examines the object and retrieves properties
        var properties = objProperty.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        #region Iterate Through Properties
        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];

            #region ArrayTypes
            if (curProp.FieldType.IsArray)
            {
                Array list = curProp.GetValue(objProperty) as Array;
                //Debug.Log("Array found");
                if (list.Length > 0)
                {
                    Type elType = curProp.GetValue(objProperty).GetType().GetElementType();

                    if (elType.IsSubclassOf(typeof(AdvancedScriptableObject)))
                    {
                        AdvancedScriptableObject[] newList = list as AdvancedScriptableObject[];
                        //Delete all elements
                        for (int x = 0; x < list.Length; x++)
                        {
                            AdvancedScriptableObject element = (AdvancedScriptableObject)newList.GetValue(x);
                            if (element != null &&
                                BShareAsset(deleteFrom, element))
                            {
                                Delete(deleteFrom, element);
                                MonoBehaviour.DestroyImmediate(element, true);
                            }
                        }
                        curProp.SetValue(objProperty, newList);
                    }
                }
            }
            #endregion
            if (!BRelevantType(curProp))
            {
                continue;
            }

            //Ensures value is not null
            var val = (AdvancedScriptableObject)curProp.GetValue(objProperty);
            if (val != null)
            {
                if (BShareAsset(deleteFrom, val))
                {
                    Delete(deleteFrom, val);
                }
            }
        }
        #endregion
        MonoBehaviour.DestroyImmediate(objProperty, true);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
Ejemplo n.º 3
0
    void AddReferenceData(SerializedProperty property)
    {
        bool bIsArrayElement;

        if (property.propertyPath.Contains("["))
        {
            bIsArrayElement = true;
        }
        else
        {
            bIsArrayElement = false;
        }

        if (!bIsArrayElement)
        {
            ASOManager.Me.AddReferenceData(parentASO, propertyASO, property.name);
        }
        else
        {
            FieldInfo   field;
            System.Type parentType = parentASO.GetType();
            string      arrayName  = AdvancedScriptableObjectUtility.GetArrayName(property);
            string      arrayIndex = "";
            field = parentType.GetField(arrayName);
            if (field != null)
            {
                var arrayElements = field.GetValue(parentASO) as Array;
                for (int i = 0; i < arrayElements.Length; i++)
                {
                    if ((AdvancedScriptableObject)arrayElements.GetValue(i) == propertyASO)
                    {
                        arrayIndex = i.ToString();
                        break;
                    }
                }
            }
            ASOManager.Me.AddReferenceData(parentASO, propertyASO, string.Format("{0}[{1}]", arrayName, arrayIndex));
        }
    }
    /// <summary>
    /// Run through all properties recursively searching for aso references and
    /// adds the references
    /// </summary>
    /// <param name="toUpdate"></param>
    public static void AddReferences(AdvancedScriptableObject toUpdate)
    {
        //Debug.Log("-----------Add References Begin---------");
        //Debug.Log(string.Format("Adding references for {0}", toUpdate.name));

        //Examines the object and retrieves properties
        var properties = toUpdate.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        #region Iterate Through Properties
        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];
            //Debug.Log(curProp.Name);
            if (curProp.FieldType.IsArray && curProp.FieldType.GetElementType().IsSubclassOf(typeof(AdvancedScriptableObject)))
            {
                #region Handle Arrays
                Array array = curProp.GetValue(toUpdate) as Array;
                if (array != null && array.Length > 0)
                {
                    for (int x = 0; x < array.Length; x++)
                    {
                        if (array.GetValue(x) != null)
                        {
                            AdvancedScriptableObject propASO = (AdvancedScriptableObject)array.GetValue(x);
                            if (!BShareAsset(toUpdate, propASO))
                            {
                                ASOManager.Me.AddReferenceData(toUpdate, propASO, curProp.Name, x);
                            }
                            else
                            {
                                //recursively enter to update child references.
                                AddReferences(propASO);
                            }
                        }
                    }
                }
                #endregion
            }
            else
            {
                if (curProp.Name == "_protoParent")
                {
                    AdvancedScriptableObject parentASO = (AdvancedScriptableObject)curProp.GetValue(toUpdate);
                    if (parentASO != null)
                    {
                        if (!parentASO.ProtoChildren.Contains(toUpdate))
                        {
                            parentASO.ProtoChildren.Add(toUpdate);
                        }
                    }
                    continue;
                }

                //Skips over irrelevant types
                if (!BRelevantType(curProp))
                {
                    continue;
                }

                //Ensures value is not null
                var val = (UnityEngine.Object)curProp.GetValue(toUpdate);
                if (val != null)
                {
                    AdvancedScriptableObject propASO = (AdvancedScriptableObject)val;

                    if (!BShareAsset(toUpdate, propASO))
                    {
                        ASOManager.Me.AddReferenceData(toUpdate, propASO, curProp.Name);
                    }
                    else
                    {
                        AddReferences(propASO);
                    }
                }
            }
        }
        #endregion

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        //Debug.Log("---------Add References End---------");
    }
    /// <summary>
    /// Removes and deletes any embedded subassets. used recursively
    /// </summary>
    /// <param name="aSObj"></param>
    public static void CleanObject(AdvancedScriptableObject aSObj)
    {
        //Debug.Log("--------BEGIN CLEANING----------");
        //Debug.Log(string.Format("Cleaning [{0}]",aSObj.name));
        //Examines the object and retrieves properties
        var properties = aSObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];

            if (BIsIgnoredField(curProp))
            {
                continue;
            }

            if (curProp.FieldType.IsArray)
            {
                Array list = curProp.GetValue(aSObj) as Array;
                if (list != null && list.Length > 0)
                {
                    Type elType = curProp.GetValue(aSObj).GetType().GetElementType();

                    if (elType.IsSubclassOf(typeof(AdvancedScriptableObject)))
                    {
                        AdvancedScriptableObject[] newList = list as AdvancedScriptableObject[];
                        //Delete all elements
                        for (int x = 0; x < list.Length; x++)
                        {
                            AdvancedScriptableObject element = (AdvancedScriptableObject)newList.GetValue(x);
                            if (element != null &&
                                BShareAsset(aSObj, element))
                            {
                                Delete(aSObj, element);
                                MonoBehaviour.DestroyImmediate(element, true);
                            }
                            else
                            {
                                ASOManager.Me.RemoveReference(aSObj, element);
                            }
                            //Null cur index
                            newList.SetValue(null, x);
                        }
                        curProp.SetValue(aSObj, null);
                    }
                    else
                    {
                        curProp.SetValue(aSObj, null);
                    }
                }
            }
            else
            {
                //Skips over irrelevant types
                if (!BRelevantType(curProp))
                {
                    continue;
                }

                //Ensures value is not null
                var val = (AdvancedScriptableObject)curProp.GetValue(aSObj);
                if (val != null)
                {
                    if (BShareAsset(aSObj, val))
                    {
                        Delete(aSObj, val);
                        MonoBehaviour.DestroyImmediate(val, true);
                    }
                    else
                    {
                        ASOManager.Me.RemoveReference(aSObj, val);
                        curProp.SetValue(aSObj, null);
                    }
                }
            }
        }
        new SerializedObject(aSObj).ApplyModifiedProperties();
        EditorUtility.SetDirty(aSObj);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        new SerializedObject(aSObj).UpdateIfRequiredOrScript();
        EditorApplication.RepaintHierarchyWindow();
        //Debug.Log("--------CLEANING FINISHED----------");
    }
    public static void CloneData(AdvancedScriptableObject destObj, AdvancedScriptableObject from, AdvancedScriptableObject to)
    {
        //Debug.Log("--------BEGIN COPYING----------");
        //Examines the object and retrieves properties
        var properties = from.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        //Iterates through it's properties setting any non merged SObj data
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];

            if (BIsIgnoredField(curProp))
            {
                continue;
            }
            //Debug.Log(string.Format("CurProp:{0}", curProp.Name));

            if (curProp.FieldType.IsArray)
            {
                #region ArrayHandling
                Type elType = curProp.FieldType.GetElementType();

                //Debug.Log(string.Format("ArrayElementType:{0}", elType.Name));

                if (elType.IsSubclassOf(typeof(AdvancedScriptableObject)))
                {
                    #region ASO Array
                    Array fromList = curProp.GetValue(from) as Array;
                    Array toList   = Array.CreateInstance(curProp.FieldType.GetElementType(), fromList.Length);

                    //Copy each element
                    for (int x = 0; x < fromList.Length; x++)
                    {
                        AdvancedScriptableObject element = (AdvancedScriptableObject)fromList.GetValue(x);

                        if (element != null)
                        {
                            //if element is merged to the asset it's being copied from.
                            if (BShareAsset(from, element))
                            {
                                var newObj = ScriptableObject.CreateInstance(element.GetType()) as AdvancedScriptableObject;

                                newObj.hideFlags = HideFlags.HideInHierarchy;
                                newObj.name      = element.name;

                                SerializedObject serObj = new SerializedObject(newObj);
                                serObj.FindProperty("_parentAsset").objectReferenceValue = to;
                                serObj.ApplyModifiedProperties();

                                //Merge the object
                                AssetDatabase.AddObjectToAsset(newObj, destObj);
                                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(newObj));

                                EditorUtility.SetDirty(destObj);
                                AssetDatabase.SaveAssets();
                                AssetDatabase.Refresh();


                                //copy the data from the other object
                                CloneData(destObj, element, newObj);
                                toList.SetValue(newObj, x);
                                new SerializedObject(to).ApplyModifiedProperties();
                                Debug.Log(string.Format("New ARray val:{0}", toList.GetValue(x)));
                            }
                            else
                            {
                                toList.SetValue(fromList.GetValue(x), x);
                                ASOManager.Me.AddReferenceData(to, element, curProp.Name, x);
                                new SerializedObject(to).ApplyModifiedProperties();
                            }
                        }
                    }
                    //Array newArray = Array.ConvertAll(toList, x => (elType)x);
                    curProp.SetValue(to, toList);

                    new SerializedObject(to).ApplyModifiedProperties();

                    EditorUtility.SetDirty(to);
                    EditorUtility.SetDirty(destObj);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();
                    #endregion
                }
                else
                {
                    #region Other Arrays

                    Array fromList = curProp.GetValue(from) as Array;
                    Array toList   = Array.CreateInstance(curProp.FieldType.GetElementType(), fromList.Length);
                    Array.Copy(fromList, toList, fromList.Length);
                    curProp.SetValue(to, toList);
                    #endregion
                }
                #endregion
            }
            else
            {
                #region Standard Properties
                //Ensures value is not null
                var valFrom = curProp.GetValue(from);
                //Debug.Log(string.Format("Field:[{0}]  Value:[{1}]", curProp.Name,valFrom));
                if (valFrom != null)
                {
                    if (!valFrom.GetType().IsSubclassOf((typeof(AdvancedScriptableObject))) &&
                        valFrom.GetType() != typeof(AdvancedScriptableObject))
                    {
                        //Debug.Log("Setting as reference");
                        curProp.SetValue(to, valFrom);
                    }
                    else
                    {
                        //If from var doesn't share asset with from object then set as reference
                        if (!BShareAsset(from, (AdvancedScriptableObject)valFrom))
                        {
                            curProp.SetValue(to, valFrom);
                            ASOManager.Me.AddReferenceData(to, (AdvancedScriptableObject)valFrom, curProp.Name);
                        }
                        else
                        {
                            //Create a new object
                            var asoFromVal = (AdvancedScriptableObject)valFrom;
                            Debug.Log(string.Format("Type of element:{0}", asoFromVal.GetType()));
                            var newObj = ScriptableObject.CreateInstance(asoFromVal.GetType()) as AdvancedScriptableObject;
                            newObj.hideFlags = HideFlags.HideInHierarchy;
                            newObj.name      = asoFromVal.name;

                            SerializedObject serObj = new SerializedObject(newObj);
                            serObj.FindProperty("_parentAsset").objectReferenceValue = to;
                            serObj.ApplyModifiedProperties();

                            //Merge the object
                            AssetDatabase.AddObjectToAsset(newObj, destObj);
                            AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(newObj));

                            curProp.SetValue(to, newObj);
                            EditorUtility.SetDirty(destObj);
                            AssetDatabase.SaveAssets();
                            AssetDatabase.Refresh();
                            //copy the data from the other object
                            CloneData(destObj, (AdvancedScriptableObject)valFrom, newObj);
                        }
                    }
                }
                #endregion
            }
        }

        new SerializedObject(to).ApplyModifiedProperties();
        EditorUtility.SetDirty(to);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        //Debug.Log("--------COPYING FINISHED----------");
    }
    public static AdvancedScriptableObject MergeAll(AdvancedScriptableObject assetToMergeWith, AdvancedScriptableObject referencingObj,
                                                    AdvancedScriptableObject toMerge, bool bInstanceMerging = false)
    {
        //Copies the object
        var toMergeCopy = MonoBehaviour.Instantiate(toMerge);

        toMergeCopy.name      = toMerge.name;
        toMergeCopy.hideFlags = HideFlags.HideInHierarchy;
        AssetDatabase.AddObjectToAsset(toMergeCopy, assetToMergeWith);
        AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(toMergeCopy));

        //Examines the object and retrieves properties
        var properties = toMerge.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);


        #region Iterate Through Properties
        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];
            //Debug.Log(curProp.Name);
            if (curProp.Name == "_parentAsset")
            {
                //Debug.Log("Setting Parent");
                curProp.SetValue(toMergeCopy, referencingObj);
            }

            if (curProp.FieldType.IsArray && curProp.FieldType.GetElementType().IsSubclassOf(typeof(AdvancedScriptableObject)))
            {
                #region Handle Arrays
                Array array    = curProp.GetValue(toMerge) as Array;
                Array newArray = curProp.GetValue(toMergeCopy) as Array;
                for (int x = 0; x < array.Length; x++)
                {
                    if (array.GetValue(x) != null)
                    {
                        if (!BShareAsset(assetToMergeWith, (AdvancedScriptableObject)array.GetValue(x)))
                        {
                            newArray.SetValue(MergeAll(assetToMergeWith, toMergeCopy, (AdvancedScriptableObject)array.GetValue(x), bInstanceMerging), x);
                        }
                    }
                }
                curProp.SetValue(toMergeCopy, newArray);
                #endregion
            }
            else
            {
                //Skips over irrelevant types
                if (!BRelevantType(curProp))
                {
                    continue;
                }

                //Ensures value is not null
                var val = (AdvancedScriptableObject)curProp.GetValue(toMerge);
                if (val != null)
                {
                    if (!BShareAsset(assetToMergeWith, val))
                    {
                        curProp.SetValue(toMergeCopy, MergeAll(assetToMergeWith, toMergeCopy, val, bInstanceMerging));
                    }
                }
            }
        }
        #endregion

        if (!bInstanceMerging)
        {
            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(toMerge));
        }
        else
        {
            ASOManager.Me.RemoveReference(assetToMergeWith, toMerge);
        }

        //update assetdatabase
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        return(toMergeCopy);
    }
    public static AdvancedScriptableObject UnmergeAll(AdvancedScriptableObject unmergeFrom, AdvancedScriptableObject toUnmerge)
    {
        //Copies the object
        var toUnmergeCopy = ScriptableObject.Instantiate(toUnmerge);

        toUnmergeCopy.name = toUnmerge.name;

        //create the Object at the same file location but not added to object
        string fileLoc    = AssetDatabase.GetAssetPath(unmergeFrom);
        string fileName   = Path.GetFileName(fileLoc);
        string folderLoc  = fileLoc.Remove(fileLoc.Length - fileName.Length);
        string uniquePath = AssetDatabase.GenerateUniqueAssetPath(folderLoc + toUnmergeCopy.name + ".asset");

        AssetDatabase.CreateAsset(toUnmergeCopy, uniquePath);

        //Examines the object and retrieves properties
        var properties = toUnmerge.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        #region Iterate Through Properties
        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];
            //Debug.Log(curProp.Name);
            if (curProp.Name == "_parentAsset")
            {
                //Debug.Log("Setting Parent");
                curProp.SetValue(toUnmergeCopy, null);
            }

            if (curProp.FieldType.IsArray && curProp.FieldType.GetElementType().IsSubclassOf(typeof(AdvancedScriptableObject)))
            {
                #region Handle Arrays
                Array array    = curProp.GetValue(toUnmerge) as Array;
                Array newArray = curProp.GetValue(toUnmergeCopy) as Array;
                for (int x = 0; x < array.Length; x++)
                {
                    AdvancedScriptableObject arrayVal = (AdvancedScriptableObject)array.GetValue(x);
                    if (arrayVal != null)
                    {
                        if (BShareAsset(unmergeFrom, arrayVal))
                        {
                            AdvancedScriptableObject unmergedPropVal = UnmergeAll(unmergeFrom, arrayVal);
                            newArray.SetValue(unmergedPropVal, x);
                            //Set up reference cachedata
                            ASOManager.Me.AddReferenceData(toUnmergeCopy, unmergedPropVal, curProp.Name, x);
                        }
                    }
                }
                curProp.SetValue(toUnmergeCopy, newArray);
                #endregion
            }
            else
            {
                //Skips over irrelevant types
                if (!BRelevantType(curProp))
                {
                    continue;
                }

                //Ensures value is not null
                var val = (AdvancedScriptableObject)curProp.GetValue(toUnmerge);

                if (val != null)
                {
                    if (BShareAsset(unmergeFrom, val))
                    {
                        //Remerge value along with children
                        AdvancedScriptableObject unmergedPropVal = UnmergeAll(unmergeFrom, val);
                        curProp.SetValue(toUnmergeCopy, unmergedPropVal);
                        ASOManager.Me.AddReferenceData(toUnmergeCopy, unmergedPropVal, curProp.Name);
                    }
                }
            }
        }
        #endregion
        MonoBehaviour.DestroyImmediate(toUnmerge, true);
        AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(toUnmergeCopy));

        //update assetdatabase
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        return(toUnmergeCopy);
    }
    public static AdvancedScriptableObject RemergeChildren(AdvancedScriptableObject toMerge)
    {
        //Examines the object and retrieves properties
        var properties = toMerge.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        #region Iterate Through Properties
        //Iterates through it's properties
        for (int i = 0; i < properties.Length; i++)
        {
            var curProp = properties[i];
            //Debug.Log(curProp.Name);

            if (curProp.FieldType.IsArray && curProp.FieldType.GetElementType().IsSubclassOf(typeof(AdvancedScriptableObject)))
            {
                #region Handle Arrays
                Array array = curProp.GetValue(toMerge) as Array;
                for (int x = 0; x < array.Length; x++)
                {
                    AdvancedScriptableObject arrayVal = (AdvancedScriptableObject)array.GetValue(x);
                    if (arrayVal != null)
                    {
                        if (BShareAsset(toMerge, arrayVal))
                        {
                            array.SetValue(MergeAll(toMerge, toMerge, arrayVal), x);
                        }
                        else
                        {
                            //set reference
                            array.SetValue(arrayVal, x);
                            ASOManager.Me.AddReferenceData(toMerge, arrayVal, curProp.Name, x);
                        }
                    }
                }
                curProp.SetValue(toMerge, array);
                #endregion
            }
            else
            {
                //Skips over irrelevant types
                if (!BRelevantType(curProp))
                {
                    continue;
                }

                //Ensures value is not null
                var val = (AdvancedScriptableObject)curProp.GetValue(toMerge);
                if (val != null)
                {
                    ////Then remerge to the copy
                    if (BShareAsset(toMerge, val))
                    {
                        curProp.SetValue(toMerge, MergeAll(toMerge, toMerge, val));
                    }
                    else
                    {
                        //Set reference
                        curProp.SetValue(toMerge, val);
                        ASOManager.Me.AddReferenceData(toMerge, val, curProp.Name);
                    }
                }
            }
        }
        #endregion
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        return(toMerge);
    }