Exemplo n.º 1
0
        /// <summary>
        /// Find references of source in mine, and set their counterparts in Theirs to copy. This "start" function calls
        /// FindRefs which searches the whole object's hierarchy, and then calls UnsetFlagRecursive to reset the flag
        /// used to avoid searching the same object twice
        /// </summary>
        /// <param name="window">The ObjectMergeWindow doing the merge</param>
        /// <param name="source">The source object to find references within</param>
        /// <param name="copy">The copy we just made of source</param>
        /// <param name="isMine">Whether the source object is on the mine (left) side</param>
        /// <returns>Iterator, for  coroutine update</returns>
        static IEnumerator FindAndSetRefs(ObjectMerge window, GameObject source, GameObject copy, bool isMine)
        {
            var root        = window.root;
            var sourceObjs  = new List <GameObject>();
            var copyObjs    = new List <GameObject>();
            var srcProps    = new List <SerializedProperty>();
            var copyProps   = new List <SerializedProperty>();
            var sourceComps = new List <Component>();
            var copyComps   = new List <Component>();

            Util.GameObjectToList(source, sourceObjs);
            yield return(null);

            Util.GameObjectToList(copy, copyObjs);
            yield return(null);

#if UNITY_4_6 || UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER
            source.GetComponentsInChildren(sourceComps);
            yield return(null);

            copy.GetComponentsInChildren(copyComps);
#else
            sourceComps.AddRange(source.GetComponents <Component>());
            yield return(null);

            copyComps.AddRange(copy.GetComponents <Component>());
#endif
            yield return(null);

            var searchList = new List <GameObjectHelper>();
            root.ToList(searchList);

            var properties = new List <PropertyHelper>();
            var props      = new List <SerializedProperty>();
            var otherProps = new List <SerializedProperty>();
            var objs       = new List <object>(searchList.Count);
            var otherObjs  = new List <GameObject>(searchList.Count);
            var comps      = new List <object>(searchList.Count);
            var otherComps = new List <Component>(searchList.Count);

            window.updateType     = RefreshType.Preparing;
            window.totalUpdateNum = searchList.Count;
            window.updateCount    = 0;
            for (var i = 0; i < searchList.Count; i++)
            {
                window.updateCount++;
                var searchObj = searchList[i];
                objs.Add(searchObj.GetObject(isMine));
                otherObjs.Add(searchObj.GetObject(!isMine));
                var searchComponents = searchObj.components;
                for (var j = 0; j < searchComponents.Count; j++)
                {
                    var comp = searchComponents[j];
                    comps.Add(comp.GetComponent(isMine));
                    otherComps.Add(comp.GetComponent(!isMine));
                    properties.Clear();
                    comp.GetFullPropertyList(properties);
                    for (var k = 0; k < properties.Count; k++)
                    {
                        var property  = properties[k];
                        var prop      = property.GetProperty(isMine);
                        var otherProp = property.GetProperty(!isMine);
                        if (prop != null && otherProp != null &&
                            prop.propertyType == SerializedPropertyType.ObjectReference &&
                            prop.objectReferenceValue != null)
                        {
                            props.Add(prop);
                            otherProps.Add(otherProp);
                        }
                    }
                }

                yield return(null);
            }

            window.updateType     = RefreshType.Copying;
            window.totalUpdateNum = sourceObjs.Count;
            window.updateCount    = 0;
            for (var i = 0; i < sourceObjs.Count; i++)
            {
                window.updateCount++;
                var sourceObject = sourceObjs[i];
                var copyObject   = copyObjs[i];

                // Find and set refs to the GameObject
                for (var j = 0; j < props.Count; j++)
                {
                    var prop      = props[j];
                    var otherProp = otherProps[j];
                    if (prop.objectReferenceValue == sourceObject)
                    {
                        //Sometimes you get an error here in older versions of Unity about using a
                        //SerializedProperty after the object has been deleted.  Don't know how else to
                        //detect this
                        otherProp.objectReferenceValue = copyObject;
                        if (window.log)
                        {
                            Debug.Log("Set reference to " + copyObject + " in "
                                      + prop.serializedObject.targetObject + "." + prop.name,
                                      prop.serializedObject.targetObject);
                        }

                        if (prop.serializedObject.targetObject != null)
                        {
                            prop.serializedObject.ApplyModifiedProperties();
                        }
                    }
                }

                yield return(null);
            }

            window.updateType     = RefreshType.Copying;
            window.totalUpdateNum = sourceComps.Count;
            window.updateCount    = 0;
            for (var i = 0; i < sourceComps.Count; i++)
            {
                window.updateCount++;
                var sourceComponent = sourceComps[i];
                // Missing scripts show up as null
                if (sourceComponent == null)
                {
                    continue;
                }

                if (sourceComponent is Transform)
                {
                    continue;
                }

                var copyComponent = copyComps[i];

                // Find and set refs to the Component
                for (var l = 0; l < props.Count; l++)
                {
                    var prop      = props[l];
                    var otherProp = otherProps[l];
                    if (prop.objectReferenceValue == sourceComponent)
                    {
                        //Sometimes you get an error here in older versions of Unity about using a
                        //SerializedProperty after the object has been deleted.  Don't know how else to
                        //detect this
                        otherProp.objectReferenceValue = copyComponent;
                        if (window.log)
                        {
                            Debug.Log("Set reference to " + copyComponent + " in "
                                      + prop.serializedObject.targetObject + "." + prop.name,
                                      prop.serializedObject.targetObject);
                        }

                        if (prop.serializedObject.targetObject != null)
                        {
                            prop.serializedObject.ApplyModifiedProperties();
                        }
                    }
                }

                yield return(null);

                //Find references outside the copied hierarchy
                srcProps.Clear();
                copyProps.Clear();
                PropertyHelper.GetProperties(srcProps, new SerializedObject(sourceComponent));
                PropertyHelper.GetProperties(copyProps, new SerializedObject(copyComponent));
                for (var j = 0; j < srcProps.Count; j++)
                {
                    var srcProp = srcProps[j];
                    if (srcProp.name == "m_Script")                     //Ignore the script
                    {
                        continue;
                    }

                    if (srcProp.propertyType == SerializedPropertyType.ObjectReference &&
                        srcProp.objectReferenceValue != null)
                    {
                        if (srcProp.objectReferenceValue == null)
                        {
                            continue;
                        }

                        var copyProp = copyProps[j];
                        if (srcProp.objectReferenceValue is GameObject)
                        {
                            var index = objs.IndexOf(srcProp.objectReferenceValue);
                            if (index >= 0)
                            {
                                var otherobj = otherObjs[index];
                                if (window.log)
                                {
                                    Debug.Log(
                                        "Set reference to " + otherobj + " in "
                                        + copyProp.serializedObject.targetObject + "." + copyProp.name,
                                        copyProp.serializedObject.targetObject);
                                }
                                copyProp.objectReferenceValue = otherobj;
                            }
                        }
                        else
                        {
                            var index = comps.IndexOf(srcProp.objectReferenceValue);
                            if (index >= 0)
                            {
                                var otherComp = otherComps[index];
                                if (window.log)
                                {
                                    Debug.Log(
                                        "Set reference to " + otherComp + " in "
                                        + copyProp.serializedObject.targetObject + "." + copyProp.name,
                                        copyProp.serializedObject.targetObject);
                                }
                                copyProp.objectReferenceValue = otherComp;
                            }
                        }

                        if (copyProp.serializedObject.targetObject != null)
                        {
                            copyProp.serializedObject.ApplyModifiedProperties();
                        }
                    }

                    yield return(null);
                }
            }
        }
        /// <summary>
        /// Find references of source in mine, and set their counterparts in Theirs to copy. This "start" function calls
        /// FindRefs which searches the whole object's hierarchy, and then calls UnsetFlagRecursive to reset the flag
        /// used to avoid searching the same object twice
        /// </summary>
        /// <param name="window">The ObjectMergeWindow doing the merge</param>
        /// <param name="source">The source object to find references within</param>
        /// <param name="copy">The copy we just made of source</param>
        /// <param name="isMine">Whether the source object is on the mine (left) side</param>
        /// <returns>Iterator, for  coroutine update</returns>
        static IEnumerator FindAndSetRefs(ObjectMerge window, UnityObject source, UnityObject copy, bool isMine)
        {
            var root = window.root;

            SrcProps.Clear();
            CopyProps.Clear();
            Properties.Clear();
            Props.Clear();
            OtherProps.Clear();
            Objs.Clear();
            OtherObjs.Clear();
            Comps.Clear();
            OtherComps.Clear();
            SearchList.Clear();

            root.ToList(SearchList);
            var count = SearchList.Count;

            window.updateType     = RefreshType.Preparing;
            window.totalUpdateNum = count;
            window.updateCount    = 0;
            for (var i = 0; i < count; i++)
            {
                window.updateCount++;
                var searchObj = SearchList[i];
                Objs.Add(searchObj.GetObject(isMine));
                OtherObjs.Add(searchObj.GetObject(!isMine));
                var searchComponents = searchObj.components;
                var componentsCount  = searchComponents.Count;
                for (var j = 0; j < componentsCount; j++)
                {
                    var comp = searchComponents[j];
                    Comps.Add(comp.GetComponent(isMine));
                    OtherComps.Add(comp.GetComponent(!isMine));
                    Properties.Clear();
                    comp.GetFullPropertyList(Properties);
                    var propertiesCount = Properties.Count;
                    for (var k = 0; k < propertiesCount; k++)
                    {
                        var property  = Properties[k];
                        var prop      = property.GetProperty(isMine);
                        var otherProp = property.GetProperty(!isMine);
                        if (prop != null && otherProp != null && prop.propertyType == SerializedPropertyType.ObjectReference &&
                            prop.objectReferenceValue != null)
                        {
                            Props.Add(prop);
                            OtherProps.Add(otherProp);
                        }
                    }
                }

                yield return(null);
            }

            window.updateType     = RefreshType.Copying;
            window.totalUpdateNum = Props.Count;
            window.updateCount    = 0;
            // Find and set refs to the Component
            for (var j = 0; j < Props.Count; j++)
            {
                var prop      = Props[j];
                var otherProp = OtherProps[j];
                if (prop.objectReferenceValue == source)
                {
                    //Sometimes you get an error here in older versions of Unity about using a
                    //SerializedProperty after the object has been deleted.  Don't know how else to
                    //detect this
                    otherProp.objectReferenceValue = copy;
                    if (window.log)
                    {
                        Debug.Log("Set reference to " + copy + " in " + prop.serializedObject.targetObject + "." + prop.name,
                                  prop.serializedObject.targetObject);
                    }

                    if (prop.serializedObject.targetObject != null)
                    {
                        prop.serializedObject.ApplyModifiedProperties();
                    }
                }

                yield return(null);
            }

            //Find references in properties
            SrcProps.Clear();
            CopyProps.Clear();
            PropertyHelper.GetProperties(SrcProps, new SerializedObject(source));
            PropertyHelper.GetProperties(CopyProps, new SerializedObject(copy));

            window.updateType     = RefreshType.Copying;
            window.totalUpdateNum = SrcProps.Count;
            window.updateCount    = 0;
            for (var j = 0; j < SrcProps.Count; j++)
            {
                window.updateCount++;
                var srcProp = SrcProps[j];
                if (srcProp.name == "m_Script" || srcProp.name == "m_Father")                 //Ignore the script and transform parent
                {
                    continue;
                }

                if (srcProp.propertyType == SerializedPropertyType.ObjectReference && srcProp.objectReferenceValue != null)
                {
                    if (srcProp.objectReferenceValue == null)
                    {
                        continue;
                    }

                    var copyProp = CopyProps[j];
                    if (srcProp.objectReferenceValue is GameObject)
                    {
                        var index = Objs.IndexOf(srcProp.objectReferenceValue);
                        if (index >= 0)
                        {
                            var otherobj = OtherObjs[index];
                            if (window.log)
                            {
                                Debug.Log(
                                    "Set reference to " + otherobj + " in " + copyProp.serializedObject.targetObject + "." + copyProp.name,
                                    copyProp.serializedObject.targetObject);
                            }

                            copyProp.objectReferenceValue = otherobj;
                        }
                    }
                    else
                    {
                        var index = Comps.IndexOf(srcProp.objectReferenceValue);
                        if (index >= 0)
                        {
                            var otherComp = OtherComps[index];
                            if (window.log)
                            {
                                Debug.Log(
                                    "Set reference to " + otherComp + " in " + copyProp.serializedObject.targetObject + "." + copyProp.name,
                                    copyProp.serializedObject.targetObject);
                            }

                            copyProp.objectReferenceValue = otherComp;
                        }
                    }

                    if (copyProp.serializedObject.targetObject != null)
                    {
                        copyProp.serializedObject.ApplyModifiedProperties();
                    }

                    yield return(null);
                }
            }
        }