Inheritance: EditorWindow
Example #1
0
 protected Helper(Helper parent, UniMergeWindow window, ObjectMerge objectMerge, SceneMerge sceneMerge)
 {
     this.parent      = parent;
     this.window      = window;
     this.objectMerge = objectMerge;
     this.sceneMerge  = sceneMerge;
 }
Example #2
0
        public ComponentHelper(Component mine, Component theirs, GameObjectHelper parent = null,
                               ObjectMerge window = null) : base(parent, window, window, null)
        {
            this.parent = parent;
            this.window = window;
            SetComponents(mine, theirs);

            type = mine ? mine.GetType() : theirs.GetType();
        }
Example #3
0
        public PropertyHelper(SerializedProperty mine, SerializedProperty theirs, string propertyPath,
                              Helper parent = null, UniMergeWindow window = null) : base(parent, window)
        {
            this.mine         = mine;
            this.theirs       = theirs;
            this.propertyPath = propertyPath;

            objectMerge = window as ObjectMerge;
            sceneMerge  = window as SceneMerge;

            gameObjectParent = parent as GameObjectHelper;
            componentParent  = parent as ComponentHelper;
            propertyParent   = parent as PropertyHelper;
        }
Example #4
0
        PropertyHelper(SerializedProperty mine, SerializedProperty theirs, string propertyPath,
                       SerializedPropertyType propertyType, GameObjectHelper gameObjectParent, ComponentHelper componentParent,
                       PropertyHelper propertyParent, Helper parent, UniMergeWindow window,
                       ObjectMerge objectMerge, SceneMerge sceneMerge) : base(parent, window, objectMerge, sceneMerge)
        {
            this.mine         = mine;
            this.theirs       = theirs;
            this.propertyPath = propertyPath;
            this.propertyType = propertyType;

            this.gameObjectParent = gameObjectParent;
            this.componentParent  = componentParent;
            this.propertyParent   = propertyParent;
        }
Example #5
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);
                }
            }
        }
Example #6
0
 public GameObjectHelper(ObjectMerge window, GameObjectHelper parent = null) : base(parent, window)
 {
     this.parent = parent;
     this.window = window;
 }
        /// <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);
                }
            }
        }
Example #8
0
        public static IEnumerator <bool> UpdatePropertyList(List <PropertyHelper> properties, SerializedObject myObject,
                                                            SerializedObject theirObject, GameObjectHelper gameObjectParent, ComponentHelper componentParent,
                                                            PropertyHelper propertyParent, ObjectMerge objectMerge, SceneMerge sceneMerge,
                                                            Helper parent, UniMergeWindow window, bool showHidden = false)
        {
            var myObjectIsNull    = myObject == null;
            var theirObjectIsNull = theirObject == null;

            if (myObjectIsNull && theirObjectIsNull)
            {
                yield break;
            }

            SerializedProperty myIterator = null;

            if (!myObjectIsNull)
            {
                myIterator = myObject.GetIterator();
            }

            SerializedProperty theirIterator = null;

            if (!theirObjectIsNull)
            {
                theirIterator = theirObject.GetIterator();
            }

            if (theirIterator != null)
            {
                theirIterator.Reset();
            }

            var            isGameObject        = (myObjectIsNull ? theirObject.targetObject : myObject.targetObject) is GameObject;
            var            isTransform         = (myObjectIsNull ? theirObject.targetObject : myObject.targetObject) is Transform;
            var            tempShowHiddenDepth = -1;
            var            tempShowHidden      = false;
            var            same           = true;
            var            mineHasNext    = myIterator != null;
            var            theirsHasNext  = theirIterator != null;
            var            lastDepth      = 0;
            PropertyHelper lastHelper     = null;
            var            root           = parent;
            var            gameObjectRoot = gameObjectParent;
            var            componentRoot  = componentParent;
            var            propertyRoot   = propertyParent;
            var            ignored        = false;

            while (mineHasNext || theirsHasNext)
            {
                var _myIterator    = myIterator;
                var _theirIterator = theirIterator;
                var iterator       = _myIterator != null && mineHasNext ? _myIterator : _theirIterator;

#if UNITY_4 || UNITY_5 || UNITY_5_3_OR_NEWER
                if (iterator.propertyType == SerializedPropertyType.Gradient)
                {
                    tempShowHiddenDepth = iterator.depth;
                    tempShowHidden      = true;
                }
                else
#endif
                if (iterator.depth == tempShowHiddenDepth)
                {
                    tempShowHidden      = false;
                    tempShowHiddenDepth = -1;
                }

                if (mineHasNext && theirsHasNext)
                {
                    if (myIterator.depth > theirIterator.depth)
                    {
                        //Catch up myIterator
                        if (showHidden || tempShowHidden)
                        {
                            mineHasNext &= myIterator.Next(!ignored);
                        }
                        else
                        {
                            mineHasNext &= myIterator.NextVisible(!ignored);
                        }
                    }
                    else if (theirIterator.depth > myIterator.depth && theirsHasNext)
                    {
                        // Catch up theirIterator
                        if (showHidden || tempShowHidden)
                        {
                            theirsHasNext &= theirIterator.Next(!ignored);
                        }
                        else
                        {
                            theirsHasNext &= theirIterator.NextVisible(!ignored);
                        }
                    }
                    else
                    {
                        if (showHidden || tempShowHidden)
                        {
                            mineHasNext   &= myIterator.Next(!ignored);
                            theirsHasNext &= theirIterator.Next(!ignored);
                        }
                        else
                        {
                            mineHasNext   &= myIterator.NextVisible(!ignored);
                            theirsHasNext &= theirIterator.NextVisible(!ignored);
                        }
                    }

                    if (mineHasNext && theirsHasNext)
                    {
                        if (myIterator.depth > theirIterator.depth)                         // Missing elements in mine
                        {
                            _theirIterator = null;
                        }

                        if (theirIterator.depth > myIterator.depth)                         // Missing elements in theirs
                        {
                            _myIterator = null;
                        }
                    }
                }
                else
                {
                    if (mineHasNext)
                    {
                        if (showHidden || tempShowHidden)
                        {
                            mineHasNext &= myIterator.Next(!ignored);
                        }
                        else
                        {
                            mineHasNext &= myIterator.NextVisible(!ignored);
                        }
                    }

                    if (theirsHasNext)
                    {
                        if (showHidden || tempShowHidden)
                        {
                            theirsHasNext &= theirIterator.Next(!ignored);
                        }
                        else
                        {
                            theirsHasNext &= theirIterator.NextVisible(!ignored);
                        }
                    }
                }

                if (!mineHasNext && !theirsHasNext)
                {
                    break;
                }

                if (!mineHasNext)
                {
                    _myIterator = null;
                }

                if (!theirsHasNext)
                {
                    _theirIterator = null;
                }

                // Get new iterator if one has become null
                // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
                if (_myIterator == null)
                {
                    iterator = _theirIterator;
                }
                else
                {
                    iterator = _myIterator;
                }

                var path = iterator.propertyPath;
                var type = iterator.propertyType;
                ignored = path == "m_Script";

                if (isGameObject)
                {
                    ignored = type == SerializedPropertyType.ObjectReference || type == SerializedPropertyType.Generic;
                }
                else if (isTransform)
                {
#if UNITY_4_5 || UNITY_4_5_0 || UNITY_4_6 || UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER
                    ignored = type != SerializedPropertyType.Vector3 && type != SerializedPropertyType.Quaternion && type != SerializedPropertyType.Float;
#elif !Unity3
                    ignored = type != SerializedPropertyType.Vector3 && type != (SerializedPropertyType)16 && type != SerializedPropertyType.Float;
#else
                    ignored = type != SerializedPropertyType.Vector3 && type != SerializedPropertyType.Float;
#endif
                }

                if (ignored)
                {
                    continue;
                }

                PropertyHelper ph    = null;
                var            count = properties.Count;
                // ReSharper disable once LoopVariableIsNeverChangedInsideLoop
                for (var i = 0; i < count; i++)
                {
                    var property = properties[i];
                    if (property.propertyPath == path)
                    {
                        ph = property;
                        break;
                    }
                }

                var depth = iterator.depth;
                if (depth > lastDepth)
                {
                    parent         = lastHelper;
                    propertyParent = lastHelper;
                }

                if (depth < lastDepth && parent != null)
                {
                    parent         = parent.parent;
                    propertyParent = propertyParent.propertyParent;
                }

                if (depth > 0)
                {
                    var children = propertyParent.children;
                    if (children != null)
                    {
                        count = children.Count;
                        for (var i = 0; i < count; i++)
                        {
                            var child = children[i];
                            if (child.propertyPath == path)
                            {
                                ph = child;
                                break;
                            }
                        }
                    }
                }

                SerializedProperty myIteratorCopy = null;
                if (_myIterator != null)
                {
                    myIteratorCopy = _myIterator.Copy();
                }

                SerializedProperty theirIteratorCopy = null;
                if (_theirIterator != null)
                {
                    theirIteratorCopy = _theirIterator.Copy();
                }

                if (ph == null)
                {
                    if (depth == 0)
                    {
                        ph = new PropertyHelper(myIteratorCopy, theirIteratorCopy, path, type,
                                                gameObjectRoot, componentRoot, propertyRoot, root, window, objectMerge, sceneMerge);
                        properties.Add(ph);
                    }
                    else
                    {
                        ph = new PropertyHelper(myIteratorCopy, theirIteratorCopy, path, type,
                                                gameObjectParent, componentParent, propertyParent, parent, window, objectMerge, sceneMerge);
                        var children = propertyParent.children;
                        if (children == null)
                        {
                            propertyParent.children = children = new List <PropertyHelper>(1);
                        }

                        children.Add(ph);
                    }
                }
                else
                {
                    ph.mine   = myIteratorCopy;
                    ph.theirs = theirIteratorCopy;
                }

                lastHelper = ph;
                lastDepth  = depth;
            }

            for (var i = 0; i < properties.Count; i++)
            {
                var property = properties[i];
                if (property.children == null)
                {
                    property.CheckSame();
                }
                else
                {
                    var enumerator = DeepCheckSame(property);
                    while (enumerator.MoveNext())
                    {
                        yield return(false);
                    }
                }

                if (!property.Same)
                {
                    same = false;
                }
            }

            yield return(same);
        }
Example #9
0
    void OnGUI()
    {
#if  UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2
        //Layout fix for older versions?
#else
        EditorGUIUtility.labelWidth = 100;
#endif
        //Ctrl + w to close
        if (Event.current.Equals(Event.KeyboardEvent("^w")))
        {
            Close();
            GUIUtility.ExitGUI();
        }

        /*
         * SETUP
         */
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
        EditorGUIUtility.LookLikeControls();
#endif
        ObjectMerge.alt = false;
        //Adjust colWidth as the window resizes
        colWidth = (position.width - UniMergeConfig.midWidth * 2 - UniMergeConfig.margin) / 2;
        if (mine == null || theirs == null ||
            mine.GetType() != typeof(Object) || mine.GetType() != typeof(Object)
            )             //|| !AssetDatabase.GetAssetPath(mine).Contains(".unity") || !AssetDatabase.GetAssetPath(theirs).Contains(".unity"))
        {
            merged = GUI.enabled = false;
        }
        if (GUILayout.Button("Merge"))
        {
            Merge(mine, theirs);
            GUIUtility.ExitGUI();
        }
        GUI.enabled = merged;
        GUILayout.BeginHorizontal();
        {
            GUI.enabled = mineContainer;
            if (!GUI.enabled)
            {
                merged = false;
            }
            if (GUILayout.Button("Unpack Mine"))
            {
                DestroyImmediate(theirsContainer);
                List <Transform> tmp = new List <Transform>();
                foreach (Transform t in mineContainer.transform)
                {
                    tmp.Add(t);
                }
                foreach (Transform t in tmp)
                {
                    t.parent = null;
                }
                DestroyImmediate(mineContainer);
                mySceneData.ApplySettings();
            }
            GUI.enabled = theirsContainer;
            if (!GUI.enabled)
            {
                merged = false;
            }
            if (GUILayout.Button("Unpack Theirs"))
            {
                DestroyImmediate(mineContainer);
                List <Transform> tmp = new List <Transform>();
                foreach (Transform t in theirsContainer.transform)
                {
                    tmp.Add(t);
                }
                foreach (Transform t in tmp)
                {
                    t.parent = null;
                }
                DestroyImmediate(theirsContainer);
                theirSceneData.ApplySettings();
            }
        }
        GUILayout.EndHorizontal();

        GUI.enabled = true;
        ObjectMerge.DrawRowHeight();

        GUILayout.BeginHorizontal();
        {
            GUILayout.BeginVertical(GUILayout.Width(colWidth));
            {
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                mine = EditorGUILayout.ObjectField("Mine", mine, typeof(Object));
#else
                mine = EditorGUILayout.ObjectField("Mine", mine, typeof(Object), true);
#endif
            }
            GUILayout.EndVertical();
            GUILayout.Space(UniMergeConfig.midWidth * 2);
            GUILayout.BeginVertical(GUILayout.Width(colWidth));
            {
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                theirs = EditorGUILayout.ObjectField("Theirs", theirs, typeof(Object));
#else
                theirs = EditorGUILayout.ObjectField("Theirs", theirs, typeof(Object), true);
#endif
            }
            GUILayout.EndVertical();
        }
        GUILayout.EndHorizontal();
        if (mine == null || theirs == null)
        {
            merged = false;
        }
        if (merged)
        {
            scroll = GUILayout.BeginScrollView(scroll);
            //Fog
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fog == theirSceneData.fog;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fog = EditorGUILayout.Toggle("Fog", mySceneData.fog);
                    }
                },
                leftButton = delegate {
                    mySceneData.fog = theirSceneData.fog;
                },
                rightButton = delegate {
                    theirSceneData.fog = mySceneData.fog;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fog = EditorGUILayout.Toggle("Fog", theirSceneData.fog);
                    }
                },
                drawButtons = mine && theirs
            });
            //Fog Color
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fogColor == theirSceneData.fogColor;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fogColor = EditorGUILayout.ColorField("Fog Color", mySceneData.fogColor);
                    }
                },
                leftButton = delegate {
                    mySceneData.fogColor = theirSceneData.fogColor;
                },
                rightButton = delegate {
                    theirSceneData.fogColor = mySceneData.fogColor;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fogColor = EditorGUILayout.ColorField("Fog Color", theirSceneData.fogColor);
                    }
                },
                drawButtons = mine && theirs
            });
            //Fog Mode
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fogMode == theirSceneData.fogMode;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fogMode = (FogMode)EditorGUILayout.EnumPopup("Fog Mode", mySceneData.fogMode);
                    }
                },
                leftButton = delegate {
                    mySceneData.fogMode = theirSceneData.fogMode;
                },
                rightButton = delegate {
                    theirSceneData.fogMode = mySceneData.fogMode;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fogMode = (FogMode)EditorGUILayout.EnumPopup("Fog Mode", theirSceneData.fogMode);
                    }
                },
                drawButtons = mine && theirs
            });
            //Fog Density
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fogDensity == theirSceneData.fogDensity;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fogDensity = EditorGUILayout.FloatField("Linear Density", mySceneData.fogDensity);
                    }
                },
                leftButton = delegate {
                    mySceneData.fogDensity = theirSceneData.fogDensity;
                },
                rightButton = delegate {
                    theirSceneData.fogDensity = mySceneData.fogDensity;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fogDensity = EditorGUILayout.FloatField("Linear Density", theirSceneData.fogDensity);
                    }
                },
                drawButtons = mine && theirs
            });
            //Linear Fog Start
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fogStartDistance == theirSceneData.fogStartDistance;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fogStartDistance = EditorGUILayout.FloatField("Linear Fog Start", mySceneData.fogStartDistance);
                    }
                },
                leftButton = delegate {
                    mySceneData.fogStartDistance = theirSceneData.fogStartDistance;
                },
                rightButton = delegate {
                    theirSceneData.fogStartDistance = mySceneData.fogStartDistance;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fogStartDistance = EditorGUILayout.FloatField("Linear Fog Start", theirSceneData.fogStartDistance);
                    }
                },
                drawButtons = mine && theirs
            });
            //Linear Fog End
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.fogEndDistance == theirSceneData.fogEndDistance;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.fogEndDistance = EditorGUILayout.FloatField("Linear Fog End", mySceneData.fogEndDistance);
                    }
                },
                leftButton = delegate {
                    mySceneData.fogEndDistance = theirSceneData.fogEndDistance;
                },
                rightButton = delegate {
                    theirSceneData.fogEndDistance = mySceneData.fogEndDistance;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.fogEndDistance = EditorGUILayout.FloatField("Linear Fog End", theirSceneData.fogEndDistance);
                    }
                },
                drawButtons = mine && theirs
            });
            //Ambient Light
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.ambientLight == theirSceneData.ambientLight;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.ambientLight = EditorGUILayout.ColorField("Ambient Light", mySceneData.ambientLight);
                    }
                },
                leftButton = delegate {
                    mySceneData.ambientLight = theirSceneData.ambientLight;
                },
                rightButton = delegate {
                    theirSceneData.ambientLight = mySceneData.ambientLight;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.ambientLight = EditorGUILayout.ColorField("Ambient Light", theirSceneData.ambientLight);
                    }
                },
                drawButtons = mine && theirs
            });
            //Skybox
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.skybox == theirSceneData.skybox;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                    { mySceneData.skybox = (Material)EditorGUILayout.ObjectField("Skybox Material", mySceneData.skybox, typeof(Material)); }
#else
                    { mySceneData.skybox = (Material)EditorGUILayout.ObjectField("Skybox Material", mySceneData.skybox, typeof(Material), false); }
#endif
                },
                leftButton = delegate {
                    mySceneData.skybox = theirSceneData.skybox;
                },
                rightButton = delegate {
                    theirSceneData.skybox = mySceneData.skybox;
                },
                right = delegate {
                    if (theirs)
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
                    { theirSceneData.skybox = (Material)EditorGUILayout.ObjectField("Skybox Material", theirSceneData.skybox, typeof(Material)); }
#else
                    { theirSceneData.skybox = (Material)EditorGUILayout.ObjectField("Skybox Material", theirSceneData.skybox, typeof(Material), false); }
#endif
                },
                drawButtons = mine && theirs
            });
            //Halo Strength
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.haloStrength == theirSceneData.haloStrength;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.haloStrength = EditorGUILayout.FloatField("Halo Strength", mySceneData.haloStrength);
                    }
                },
                leftButton = delegate {
                    mySceneData.haloStrength = theirSceneData.haloStrength;
                },
                rightButton = delegate {
                    theirSceneData.haloStrength = mySceneData.haloStrength;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.haloStrength = EditorGUILayout.FloatField("Halo Strength", theirSceneData.haloStrength);
                    }
                },
                drawButtons = mine && theirs
            });
            //Flare Strength
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.flareStrength == theirSceneData.flareStrength;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.flareStrength = EditorGUILayout.FloatField("Flare Strength", mySceneData.flareStrength);
                    }
                },
                leftButton = delegate {
                    mySceneData.flareStrength = theirSceneData.flareStrength;
                },
                rightButton = delegate {
                    theirSceneData.flareStrength = mySceneData.flareStrength;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.flareStrength = EditorGUILayout.FloatField("Flare Strength", theirSceneData.flareStrength);
                    }
                },
                drawButtons = mine && theirs
            });
            //Flare Fade Speed
            ObjectMerge.DrawGenericRow(new ObjectMerge.GenericRowArguments {
                indent   = 0,
                colWidth = colWidth,
                compare  = delegate {
                    bool same = GenericCompare();
                    if (same)
                    {
                        same = mySceneData.flareFadeSpeed == theirSceneData.flareFadeSpeed;
                    }
                    return(same);
                },
                left = delegate {
                    if (mine)
                    {
                        mySceneData.flareFadeSpeed = EditorGUILayout.FloatField("Flare Fade Speed", mySceneData.flareFadeSpeed);
                    }
                },
                leftButton = delegate {
                    mySceneData.flareFadeSpeed = theirSceneData.flareFadeSpeed;
                },
                rightButton = delegate {
                    theirSceneData.flareFadeSpeed = mySceneData.flareFadeSpeed;
                },
                right = delegate {
                    if (theirs)
                    {
                        theirSceneData.flareFadeSpeed = EditorGUILayout.FloatField("Flare Fade Speed", theirSceneData.flareFadeSpeed);
                    }
                },
                drawButtons = mine && theirs
            });
            GUILayout.EndScrollView();
        }
    }