static KeyValuePair<GUIContent, System.Action>[] GetButtonsData(PEPrefabScript prefabInstance, SerializedProperty prefabProperty, SerializedProperty instanceProperty)
		{
			var buttons = new KeyValuePair<GUIContent, System.Action>[] {
				new KeyValuePair<GUIContent, System.Action>(new GUIContent("Revert", "Revert property to prefab value"), () => 
				{
					if (prefabProperty == null)
						return;
					if (instanceProperty.propertyType == SerializedPropertyType.ObjectReference)
					{
						var link = prefabInstance.GetDiffWith().Links[prefabProperty.objectReferenceValue];
						if (link == null)
							instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
						else
						{
							var instanceLink = prefabInstance.Links[link];
							if (instanceLink != null)
								instanceProperty.SetPropertyValue(prefabInstance.Links[link].InstanceTarget);
							else
							{
								if (PEPrefs.DebugLevel > 0)
									Debug.Log("Link null");
								instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
							}
						}
					}
					else
					{
						instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
					}
					instanceProperty.serializedObject.ApplyModifiedProperties();
				}),
				new KeyValuePair<GUIContent, System.Action>(new GUIContent("Update", "Update changes"), () => EditorApplication.delayCall += prefabInstance.BuildModifications),
			};
			return buttons;
		}
 static internal void BuildLinks(this PEPrefabScript _this, bool force = false)
 {
     if (force || _this.Prefab == _this.gameObject)
     {
         _this.Links.BuildLinks(_this.gameObject);
         EditorUtility.SetDirty(_this);
     }
     else
     {
         if (_this == null)
         {
             Debug.LogError("PEPrefabScriptExt.BuildLinks() - _this == null");
             return;
         }
         if (_this.Prefab == null)
         {
             Debug.LogError(string.Format("PEPrefabScriptExt.BuildLinks(_this.name='{0}') - _this.Prefab == null. PrefabPath:{1}", _this.name, AssetDatabase.GetAssetOrScenePath(_this)));
             return;
         }
         PEPrefabScript pePrefabScript = _this.Prefab.GetComponent <PEPrefabScript>();
         if (pePrefabScript == null)
         {
             Debug.LogError(string.Format("PEPrefabScriptExt.BuildLinks(_this.name='{0}') - expecting prefab with _this.Prefab.name='{1}' to have attached PEPrefabScript Component. PrefabPath:{2} (Click on this message to show this prefab in Project window)", _this.name, _this.Prefab.name, AssetDatabase.GetAssetPath(_this.Prefab)), _this.Prefab);
             return;
         }
         pePrefabScript.BuildLinks();
         EditorUtility.SetDirty(pePrefabScript);
     }
 }
Beispiel #3
0
        static void ApplyModifications(this PEPrefabScript _this, PEPrefabScript targetInstance)
        {
            targetInstance.Modifications = _this.Modifications;
            var modificatedList = new List <SerializedObject>();

            foreach (var modification in _this.Modifications.Modificated)
            {
                if (modification.Mode == PEModifications.PropertyData.PropertyMode.Ignore)
                {
                    continue;
                }

                if (modification.Object == null)
                {
                    continue;
                }

                var selfObject = new SerializedObject(modification.Object);

                var linkedObject = targetInstance.Links[modification.ObjeckLink];
                if (linkedObject == null || linkedObject.InstanceTarget == null)
                {
                    continue;
                }

                var targetObject = new SerializedObject(linkedObject.InstanceTarget);

                var selfProperty   = selfObject.FindProperty(modification.PropertyPath);
                var targetProperty = targetObject.FindProperty(modification.PropertyPath);

                if (targetProperty == null)
                {
                    Debug.Log("Property not found " + modification.PropertyPath);
                }
                else
                {
                    var value = selfProperty.GetPropertyValue();
                    if (selfProperty.propertyType == SerializedPropertyType.ObjectReference)
                    {
                        var selfValue = selfProperty.GetPropertyValue();

                        var selfLink   = _this.Links[selfValue as Object];
                        var targetLink = targetInstance.Links[selfLink];

                        if (targetLink != null)
                        {
                            value = targetLink.InstanceTarget;
                        }
                    }
                    targetProperty.SetPropertyValue(value);
                    targetObject.ApplyModifiedProperties();
                }
            }

            foreach (var po in modificatedList)
            {
                po.ApplyModifiedProperties();
            }
        }
Beispiel #4
0
 public void Fill(PEPrefabScript script)
 {
     script.Properties       = this.Properties;
     script.Links            = this.Links;
     script.Modifications    = this.Modifications;
     script.ParentPrefabGUID = this.ParentPrefabGUID;
     script.PrefabGUID       = this.PrefabGUID;
 }
Beispiel #5
0
            public PrefabInternalData(PEPrefabScript script)
            {
                this.Properties    = script.Properties;
                this.Links         = script.Links;
                this.Modifications = script.Modifications;

                this.ParentPrefabGUID = script.ParentPrefabGUID;
                this.PrefabGUID       = script.PrefabGUID;
            }
        static internal PEPrefabScript GetDiffWith(this PEPrefabScript _this)
        {
            var go = _this.ParentPrefab != null &&
                     (PrefabUtility.GetPrefabParent(_this.gameObject) == _this.Prefab ||
                      PEUtils.FindRootPrefab(_this.gameObject) == _this.Prefab)
                                ? _this.ParentPrefab :
                     _this.Prefab;

            return(go != null?go.GetComponent <PEPrefabScript>() : null);
        }
        static internal void RevertToParent(this PEPrefabScript _this)
        {
            _this.Modifications = new PEModifications();
            var thisPrefab       = _this.Prefab;
            var thisParentPrefab = _this.ParentPrefab;

            var newInstance = _this.ReplaceInPlace(_this.ParentPrefab, false);

            newInstance.Prefab       = thisPrefab;
            newInstance.ParentPrefab = thisParentPrefab;
        }
Beispiel #8
0
 static internal void BuildLinks(this PEPrefabScript _this, bool force = false)
 {
     if (force || _this.Prefab == _this.gameObject)
     {
         _this.Links.BuildLinks(_this.gameObject);
         EditorUtility.SetDirty(_this);
     }
     else
     {
         _this.Prefab.GetComponent <PEPrefabScript>().BuildLinks();
         EditorUtility.SetDirty(_this.Prefab.GetComponent <PEPrefabScript>());
     }
 }
Beispiel #9
0
        static internal void DoApply(PEPrefabScript script)
        {
            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log("DoApply Start");
            }

            script.ApplyChanges(true);

            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log("DoApply Completed");
            }

            DoAutoSave();
        }
Beispiel #10
0
        static IEnumerator SelectObjectRoutine(PEPrefabScript prefabInstance)
        {
            EditorGUIUtility.ShowObjectPicker <GameObject>(null, false, "t:Prefab", 1);
            Object obj = null;

            while (EditorGUIUtility.GetObjectPickerControlID() == 1)
            {
                obj = EditorGUIUtility.GetObjectPickerObject();

                yield return(null);
            }
            if (obj != null && EditorUtility.DisplayDialog("Replace", string.Format("Do you want to replace {0} with {1}", prefabInstance.gameObject.name, obj.name), "Replace", "Cancel"))
            {
                prefabInstance.ReplaceInPlace(obj as GameObject, EditorUtility.DisplayDialog("Replace", "Apply modifications from current instance?", "Apply", "Don't apply"), false);
            }
        }
        static public bool CheckPrefab(this PEPrefabScript prefabScript)
        {
            if (prefabScript == null)
            {
                return(true);
            }

            var prefabAsset = prefabScript.Prefab;

            if (prefabAsset == null)
            {
                if (!string.IsNullOrEmpty(prefabScript.PrefabGUID))
                {
                    Debug.LogErrorFormat(prefabScript.gameObject, "Prefab asset is missing. Prefab has a reference to missing prefab asset. Asset GUID:{0}, PrefabPath:{1}", prefabScript.PrefabGUID, AssetDatabase.GetAssetOrScenePath(prefabScript));
                }
                return(false);
            }

            var prefabAssetScript = prefabAsset.GetComponent <PEPrefabScript>();

            if (prefabAssetScript == null)
            {
                Debug.LogErrorFormat(prefabAsset, "Prefab asset script is missing. Prefab has a reference to prefab asset, that must have attached PrefabScript. Asset GUID:{0}, AssetPath:{1} PrefabPath:{2}", prefabScript.PrefabGUID, AssetDatabase.GetAssetPath(prefabAsset), AssetDatabase.GetAssetOrScenePath(prefabScript));
                return(false);
            }

            if (!string.IsNullOrEmpty(prefabScript.ParentPrefabGUID))
            {
                var parentPrefabAsset = prefabScript.ParentPrefab;
                if (parentPrefabAsset == null)
                {
                    Debug.LogErrorFormat(prefabScript.gameObject, "Parent Prefab asset is missing. Prefab has a reference to missing prefab asset. Asset GUID:{0}, PrefabPath:{1}", prefabScript.ParentPrefabGUID, AssetDatabase.GetAssetOrScenePath(prefabScript));
                    return(false);
                }

                var parentPrefabAssetScript = parentPrefabAsset.GetComponent <PEPrefabScript>();
                if (parentPrefabAssetScript == null)
                {
                    Debug.LogErrorFormat(parentPrefabAsset, "Parent Prefab asset script is missing. Prefab has a reference to prefab asset, that must have attached PrefabScript. Asset GUID:{0}, AssetPath:{1} PrefabPath:{2}", prefabScript.ParentPrefabGUID, AssetDatabase.GetAssetPath(parentPrefabAsset), AssetDatabase.GetAssetOrScenePath(prefabScript));
                    return(false);
                }
            }

            return(true);
        }
Beispiel #12
0
 static void OnValidate(this PEPrefabScript _this)
 {
     if (PrefabUtility.GetPrefabType(_this.gameObject) == PrefabType.Prefab)
     {
         EditorApplication.delayCall += () =>
         {
             if (_this == null)
             {
                 return;
             }
             if (_this.Prefab != _this.gameObject && _this.transform == _this.transform.root)
             {
                 _this.Prefab = _this.gameObject;
                 _this.BuildLinks();
             }
         };
     }
 }
        static internal void BuildModifications(this PEPrefabScript _this)
        {
            var type = PrefabUtility.GetPrefabType(_this.gameObject);

            if (type != PrefabType.ModelPrefab)
            {
                var diff = _this.GetDiffWith();
                if (diff == null)
                {
                    Debug.LogError(_this.name + " : " + "Diff Object is not exists");
                    return;
                }

                _this.Modifications.CalculateModifications(_this.GetDiffWith(), _this);
            }

            _this.InvokeOnBuildModifications();
        }
        static KeyValuePair <GUIContent, System.Action>[] GetButtonsData(PEPrefabScript prefabInstance, SerializedProperty prefabProperty, SerializedProperty instanceProperty)
        {
            var buttons = new KeyValuePair <GUIContent, System.Action>[] {
                new KeyValuePair <GUIContent, System.Action>(new GUIContent("Revert", "Revert property to prefab value"), () =>
                {
                    if (prefabProperty == null)
                    {
                        return;
                    }
                    if (instanceProperty.propertyType == SerializedPropertyType.ObjectReference)
                    {
                        var link = prefabInstance.GetDiffWith().Links[prefabProperty.objectReferenceValue];
                        if (link == null)
                        {
                            instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
                        }
                        else
                        {
                            var instanceLink = prefabInstance.Links[link];
                            if (instanceLink != null)
                            {
                                instanceProperty.SetPropertyValue(prefabInstance.Links[link].InstanceTarget);
                            }
                            else
                            {
                                if (PEPrefs.DebugLevel > 0)
                                {
                                    Debug.Log("Link null");
                                }
                                instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
                            }
                        }
                    }
                    else
                    {
                        instanceProperty.SetPropertyValue(prefabProperty.GetPropertyValue());
                    }
                    instanceProperty.serializedObject.ApplyModifiedProperties();
                }),
                new KeyValuePair <GUIContent, System.Action>(new GUIContent("Update", "Update changes"), () => EditorApplication.delayCall += prefabInstance.BuildModifications),
            };

            return(buttons);
        }
Beispiel #15
0
		static internal void GetProperties(this PEModifications.PropertyData _this, out SerializedProperty prefabProperty, out SerializedProperty objectProperty, PEPrefabScript script)
		{
			var couple = _this.UserData as PropertyCouple;
			if (couple == null)
			{
				couple = new PropertyCouple();
				if (couple.objectProperty == null)
				{
					var so = new SerializedObject(_this.Object);

					if (so != null)
						couple.objectProperty = so.FindProperty(_this.PropertyPath);

					if (couple.objectProperty == null)
					{
						if (PEPrefs.DebugLevel > 0)
							Debug.Log(string.Format("Property {0} not found on Object {1}", _this.PropertyPath, _this.Object));
					}
				}

				if (couple.prefabProperty == null)
				{
					var prefabObject = script.Links.GetPrefabObject(script.GetDiffWith().gameObject, _this.Object);

					if (prefabObject != null)
					{
						var so = new SerializedObject(prefabObject);
						if (so != null)
							couple.prefabProperty = so.FindProperty(_this.PropertyPath);
					}
					else
					{
						Debug.LogWarning("Prefab object for prefab property modifications is not found");
					}
				}
			}

			prefabProperty = couple.prefabProperty;
			objectProperty = couple.objectProperty;
			_this.UserData = couple;
		}
        static internal void DoApply(PEPrefabScript script)
        {
            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log("DoApply Start");
            }

            try
            {
                AssetDatabase.StartAssetEditing();
                script.ApplyChanges(true);
            }
            finally
            {
                AssetDatabase.StopAssetEditing();
            }
            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log("DoApply Completed");
            }

            DoAutoSave();
        }
Beispiel #17
0
        static internal void InjectChild(PEPrefabScript obj, GameObject[] children)
        {
            var path = AssetDatabase.GenerateUniqueAssetPath(System.IO.Path.ChangeExtension(AssetDatabase.GUIDToAssetPath(obj.PrefabGUID), null) + "_Child_Injected.prefab");

            var go = PrefabUtility.CreatePrefab(path, obj.gameObject, ReplacePrefabOptions.Default);

            var prefabInstance = go.GetComponent <PEPrefabScript>();

            prefabInstance.Prefab           = go;
            prefabInstance.ParentPrefabGUID = obj.PrefabGUID;
            prefabInstance.BuildModifications();

            Selection.activeObject = PrefabUtility.InstantiatePrefab(go);
            AssetDatabase.ImportAsset(path);

            PECache.Instance.CheckPrefab(path);

            foreach (var child in children)
            {
                child.GetComponent <PEPrefabScript>().ParentPrefabGUID = AssetDatabase.AssetPathToGUID(path);
                PECache.Instance.CheckPrefab(AssetDatabase.GUIDToAssetPath(child.GetComponent <PEPrefabScript>().PrefabGUID));
            }
        }
Beispiel #18
0
	static IEnumerable<Object> GetRemovedObjects(Object go, PEPrefabScript prefabInstance)
	{
		foreach (var liif in prefabInstance.Modifications.RemovedObjects)
		{
			var instanceObj = prefabInstance.GetDiffWith().Links[liif];
			if (instanceObj == null)
				continue;

			var removedGO = instanceObj.InstanceTarget as GameObject;
			var removedComponent = instanceObj.InstanceTarget as Component;

			if (removedComponent is PEPrefabScript)
				continue;

			var remoteParent = (removedGO != null) ? (removedGO.transform.parent == null ? removedGO.transform.gameObject : removedGO.transform.parent.gameObject) : (removedComponent != null ? removedComponent.gameObject : null);

			var localLink = prefabInstance.Links[prefabInstance.GetDiffWith().Links[remoteParent]];
			if (localLink == null)
				continue;

			var localParent = localLink.InstanceTarget;

			if (localParent == go)
				yield return instanceObj.InstanceTarget;
		}
	}
Beispiel #19
0
        internal static void CalculateModifications(this PEModifications _this, PEPrefabScript prefab, PEPrefabScript instance)
        {
            instance.Modifications.Modificated.RemoveAll(m => m.Mode == PEModifications.PropertyData.PropertyMode.Default);
            var counter = 0;
            foreach (var link in instance.Links.Links)
            {
                if (link == null || link.InstanceTarget == null || link.InstanceTarget == instance || link.InstanceTarget is PEPrefabScript)
                    continue;

                var so = new SerializedObject(link.InstanceTarget);

                var property = so.GetIterator();

                var prefabObjectLink = prefab.Links[link];
                if (prefabObjectLink == null)
                    continue;

                var prefabObject = prefabObjectLink.InstanceTarget;

                if (prefabObject == null)
                    continue;

                var prefabSerializedObject = new SerializedObject(prefabObject);

                while (property.Next(CheckChild(property)))
                {
                    counter++;
                    if (PEUtils.PropertyFilter(property))
                    {
                        continue;
                    }

                    var prefabProperty = prefabSerializedObject.FindProperty(property.propertyPath);

                    var isArray = property.propertyPath.Contains(".Array.data[");

                    if (prefabProperty == null && !isArray)
                    {
                        if (PEPrefs.DebugLevel > 0)
                            Debug.Log("Property not found(Some times its happens) " + property.propertyPath);
                        continue;
                    }

                    var instanceValue = property.GetPropertyValue();

                    var prefabValue = prefabProperty == null ? null : prefabProperty.GetPropertyValue();
                    var isChanged = !object.Equals(instanceValue, prefabValue);
                    if (isChanged)
                    {
                        if (property.propertyType == SerializedPropertyType.ObjectReference)
                        {
                            var instanceLink = instance.Links[instanceValue as Object];
                            var prefabLink = prefab.Links[prefabValue as Object];

                            if (prefabLink != null && instanceLink != null)
                                isChanged = prefabLink.LIIF != instanceLink.LIIF;
                        }
                        else
                        {
                            var animationCurve = instanceValue as AnimationCurve;
                            if (animationCurve != null)
                            {
                                isChanged = !PEUtils.Compare(animationCurve, prefabValue as AnimationCurve);
                            }
                        }
                    }

                    if (!isChanged)
                        continue;

                    instance.Modifications.AddModification(new PEModifications.PropertyData {
                        Object = link.InstanceTarget,
                        PropertyPath = property.propertyPath,
                        ObjeckLink = link.LIIF,
                    });
                }
            }

            instance.Modifications.CalculateStructureDiff(prefab, instance);
        }
Beispiel #20
0
        private static void CalculateStructureDiff(this PEModifications _this, PEPrefabScript prefab, PEPrefabScript instance)
        {
            _this.NonPrefabObjects.Clear();
            var hierarchy = EditorUtility.CollectDeepHierarchy(new[] { instance });
            foreach (var transform in hierarchy.OfType<Transform>())
            {
                if (transform.parent == null)
                    continue;

                var link = prefab.Links[instance.Links[transform]];
                if (link != null)
                    continue;

                _this.NonPrefabObjects.Add(new PEModifications.HierarchyData {
                    child = transform,
                    parent = transform.parent
                });
            }

            _this.NonPrefabComponents.Clear();
            foreach (var component in hierarchy.Where(obj => !(obj is Transform)).OfType<Component>())
            {
                var link = prefab.Links[instance.Links[component]];
                if (link != null || prefab.Links[instance.Links[component.gameObject.transform]] == null)
                    continue;

                _this.NonPrefabComponents.Add(new PEModifications.ComponentsData {
                    child = component,
                    parent = component.gameObject
                });
            }

            _this.RemovedObjects.Clear();
            foreach (var link in prefab.Links.Links)
            {
                if (link.InstanceTarget is Transform)
                    continue;

                if (instance.Links[link] == null || instance.Links[link].InstanceTarget == null)
                    _this.RemovedObjects.Add(link.LIIF);
            }

            _this.TransformParentChanges.Clear();
            foreach (var link in instance.Links.Links)
            {
                var transform = link.InstanceTarget as Transform;
                if (transform == null)
                    continue;

                var currentTransform = transform;
                if (currentTransform == instance.transform)
                    continue;

                var currentTransformParent = currentTransform.parent;
                if (prefab.Links[link] == null)
                    continue;

                var otherTransform = prefab.Links[link].InstanceTarget as Transform;

                var otherTransformParent = otherTransform.parent;

                if (prefab.Links[otherTransformParent] == null || instance.Links[currentTransformParent] == null
                    || prefab.Links[otherTransformParent].LIIF
                    != instance.Links[currentTransformParent].LIIF)
                    _this.TransformParentChanges.Add(new PEModifications.HierarchyData {
                        child = currentTransform,
                        parent = currentTransformParent
                    });
            }
        }
        static internal PEPrefabScript ReplaceInPlace(this PEPrefabScript _this, GameObject prefabObject, bool applyModifications = true, bool keepPrefabLink = true)
        {
            var newObject = PrefabUtility.InstantiatePrefab(prefabObject) as GameObject;

            PEUtils.SetParentAndSaveLocalTransform(newObject.transform, _this.transform.parent);
            newObject.transform.SetSiblingIndex(_this.transform.GetSiblingIndex());

            PrefabUtility.DisconnectPrefabInstance(newObject);
            PrefabUtility.DisconnectPrefabInstance(_this.gameObject);

            var newObjectPrefabInstance = newObject.GetComponent <PEPrefabScript>();

            if (newObjectPrefabInstance == null)
            {
                Debug.LogWarning("EvolvePrefab not found on replacing object");
            }

            newObject.transform.localPosition = _this.transform.localPosition;

            if (prefabObject == _this.ParentPrefab || !applyModifications)
            {
                foreach (var link in _this.Links.Links)
                {
                    if (newObjectPrefabInstance.Links[link] == null)
                    {
                        newObjectPrefabInstance.Links.Links.Add(link);
                    }
                }
            }

            if (applyModifications && newObjectPrefabInstance)
            {
                _this.ApplyModifications(newObjectPrefabInstance);
            }

            var replaceDict = new Dictionary <Object, Object>();

            replaceDict.Add(_this.gameObject, newObject);
            replaceDict.Add(_this.transform, newObject.transform);

            if (newObjectPrefabInstance)
            {
                foreach (var link in _this.Links.Links)
                {
                    var from = link.InstanceTarget;
                    var to   = newObjectPrefabInstance.Links[link.LIIF];

                    if (from == null || to == null)
                    {
                        continue;
                    }

                    if (from == _this.gameObject || from == _this.transform)
                    {
                        continue;
                    }

                    replaceDict.Add(from, to.InstanceTarget);
                }
            }

            var destroyList = new List <GameObject>();

            foreach (var link in _this.Links.Links)
            {
                if (link == null || link.InstanceTarget is Component)
                {
                    continue;
                }

                var go = link.InstanceTarget as GameObject;

                if (!go)
                {
                    continue;
                }

                if (_this.Modifications.NonPrefabObjects.Any(m => m.child == go.transform))
                {
                    continue;
                }

                destroyList.Add(go);
            }

            PEUtils.ReplaceReference(_this.transform.root, replaceDict);

            var npo = _this.Modifications.NonPrefabObjects.Where(tm => tm != null && tm.child != null && tm.parent != null);

            {
                var indID   = 0;
                var indexes = new List <int>(npo.Select(n => n.child.GetSiblingIndex()));
                npo.Foreach(transformModification => PEUtils.SetParentAndSaveLocalTransform(transformModification.child, transformModification.parent));
                npo.Foreach(transformModification => transformModification.child.SetSiblingIndex(indexes [indID++]));
            }
            var reversedComponents = _this.Modifications.NonPrefabComponents.Reverse <PEModifications.ComponentsData> ();
            var newComponents      = new List <Component> ();

            foreach (var nonPrefabComponent in reversedComponents)
            {
                Component newComponent;
                newComponents.Add(newComponent = nonPrefabComponent.child.CopyComponentTo(nonPrefabComponent.parent));
                PEUtils.CopyPrefabInternalData(nonPrefabComponent.child, newComponent);
            }

            var i = 0;

            foreach (var nonPrefabComponent in reversedComponents)
            {
                var newComponent = newComponents[i++];
                if (newComponent)
                {
                    PEUtils.ReplaceReference(nonPrefabComponent.parent.transform.root, nonPrefabComponent.child, newComponent);
                    replaceDict.Add(nonPrefabComponent.child, newComponent);
                }
            }

            if (applyModifications)
            {
                foreach (var transformModification in _this.Modifications.TransformParentChanges)
                {
                    var index = transformModification.child.GetSiblingIndex();
                    PEUtils.SetParentAndSaveLocalTransform(transformModification.child, transformModification.parent);
                    transformModification.child.SetSiblingIndex(index);
                }

                foreach (var id in _this.Modifications.RemovedObjects)
                {
                    var link = newObjectPrefabInstance.Links[id];

                    if (PEPrefs.DebugLevel > 0 && link != null)
                    {
                        Debug.Log(string.Format("Object to remove: {0} {1}", id, link.InstanceTarget));
                    }

                    if (link != null && link.InstanceTarget)
                    {
                        if (PEPrefs.DebugLevel > 0)
                        {
                            Debug.Log(string.Format("Destroy Object: {0}", link.InstanceTarget));
                        }

                        if (link.InstanceTarget == newObject || link.InstanceTarget == newObjectPrefabInstance)
                        {
                            Debug.LogError("Inconsistent Destroying while replacing");
                            continue;
                        }

                        Object.DestroyImmediate(link.InstanceTarget);
                    }
                }
            }

            if (keepPrefabLink)
            {
                newObjectPrefabInstance.ParentPrefab = _this.ParentPrefab;
                newObjectPrefabInstance.Prefab       = _this.Prefab;
            }

            foreach (var kv in replaceDict)
            {
                PEUtils.CopyPrefabInternalData(kv.Key, kv.Value);
            }

            newObject.name = _this.gameObject.name;
            Object.DestroyImmediate(_this.gameObject);

            foreach (var go in destroyList)
            {
                if (go == null)
                {
                    continue;
                }

                if (go == newObject)
                {
                    Debug.LogError("Inconsistend Destroying while replacing");
                    continue;
                }

                Object.DestroyImmediate(go);
            }

            if (newObjectPrefabInstance)
            {
                newObjectPrefabInstance.BuildModifications();
                EditorUtility.SetDirty(newObjectPrefabInstance);

                if (prefabObject == _this.ParentPrefab)
                {
                    newObjectPrefabInstance.Properties = _this.Properties;
                }

                if (newObjectPrefabInstance.gameObject == null)
                {
                    Debug.LogError("New GameObject is destroyed while replacing... o_O");
                }
            }

            try
            {
                newObjectPrefabInstance.gameObject.name = newObjectPrefabInstance.gameObject.name;
            }
            catch (MissingReferenceException)
            {
                Debug.LogError("New EvolvePrefabScript is destroyed while replacing");
            }
            catch (System.NullReferenceException)
            {
            }

            return(newObjectPrefabInstance);
        }
 static internal void Revert(this PEPrefabScript _this)
 {
     _this.Modifications = new PEModifications();
     _this.ReplaceInPlace(_this.Prefab, false);
 }
        static internal void CalculateModifications(this PEModifications _this, PEPrefabScript prefab, PEPrefabScript instance)
        {
            instance.Modifications.Modificated.RemoveAll(m => m.Mode == PEModifications.PropertyData.PropertyMode.Default);
            var counter = 0;

            foreach (var link in instance.Links.Links)
            {
                if (link == null || link.InstanceTarget == null || link.InstanceTarget == instance || link.InstanceTarget is PEPrefabScript)
                {
                    continue;
                }

                var so = new SerializedObject(link.InstanceTarget);

                var property = so.GetIterator();

                var prefabObjectLink = prefab.Links[link];
                if (prefabObjectLink == null)
                {
                    continue;
                }

                var prefabObject = prefabObjectLink.InstanceTarget;

                if (prefabObject == null)
                {
                    continue;
                }

                var prefabSerializedObject = new SerializedObject(prefabObject);

                while (property.Next(CheckChild(property)))
                {
                    counter++;
                    if (PEUtils.PropertyFilter(property))
                    {
                        continue;
                    }

                    var prefabProperty = prefabSerializedObject.FindProperty(property.propertyPath);

                    var isArray     = property.propertyPath.Contains(".Array.data[");
                    var isInherited = link.InstanceTarget.GetType().IsSubclassOf(prefabObject.GetType());
                    if (prefabProperty == null && !isArray && !isInherited)
                    {
                        if (PEPrefs.DebugLevel > 0)
                        {
                            Debug.Log("Property not found(Some times its happens) " + property.propertyPath);
                        }
                        continue;
                    }

                    var instanceValue = property.GetPropertyValue();

                    var prefabValue = prefabProperty == null ? null : prefabProperty.GetPropertyValue();
                    var isChanged   = !object.Equals(instanceValue, prefabValue);
                    if (isChanged)
                    {
                        if (property.propertyType == SerializedPropertyType.ObjectReference)
                        {
                            var instanceLink = instance.Links[instanceValue as Object];
                            var prefabLink   = prefab.Links[prefabValue as Object];

                            if (prefabLink != null && instanceLink != null)
                            {
                                isChanged = prefabLink.LIIF != instanceLink.LIIF;
                            }
                        }
                        else
                        {
                            var animationCurve = instanceValue as AnimationCurve;
                            if (animationCurve != null)
                            {
                                isChanged = !PEUtils.Compare(animationCurve, prefabValue as AnimationCurve);
                            }
                        }
                    }

                    if (!isChanged)
                    {
                        continue;
                    }

                    instance.Modifications.AddModification(new PEModifications.PropertyData {
                        Object       = link.InstanceTarget,
                        PropertyPath = property.propertyPath,
                        ObjeckLink   = link.LIIF,
                    });
                }
            }

            instance.Modifications.CalculateStructureDiff(prefab, instance);
        }
        static private void CalculateStructureDiff(this PEModifications _this, PEPrefabScript prefab, PEPrefabScript instance)
        {
            _this.NonPrefabObjects.Clear();
            var hierarchy = EditorUtility.CollectDeepHierarchy(new[] { instance });

            foreach (var transform in hierarchy.OfType <Transform>())
            {
                if (transform.parent == null)
                {
                    continue;
                }

                var link = prefab.Links[instance.Links[transform]];
                if (link != null)
                {
                    continue;
                }

                _this.NonPrefabObjects.Add(new PEModifications.HierarchyData {
                    child  = transform,
                    parent = transform.parent
                });
            }

            _this.NonPrefabComponents.Clear();
            foreach (var component in hierarchy.Where(obj => !(obj is Transform)).OfType <Component>())
            {
                var link = prefab.Links[instance.Links[component]];
                if (link != null || prefab.Links[instance.Links[component.gameObject.transform]] == null)
                {
                    continue;
                }

                _this.NonPrefabComponents.Add(new PEModifications.ComponentsData {
                    child  = component,
                    parent = component.gameObject
                });
            }

            _this.RemovedObjects.Clear();
            foreach (var link in prefab.Links.Links)
            {
                if (link.InstanceTarget is Transform)
                {
                    continue;
                }

                if (instance.Links[link] == null || instance.Links[link].InstanceTarget == null)
                {
                    _this.RemovedObjects.Add(link.LIIF);
                }
            }

            _this.TransformParentChanges.Clear();
            foreach (var link in instance.Links.Links)
            {
                var transform = link.InstanceTarget as Transform;
                if (transform == null)
                {
                    continue;
                }

                var currentTransform = transform;
                if (currentTransform == instance.transform)
                {
                    continue;
                }

                var currentTransformParent = currentTransform.parent;
                if (prefab.Links[link] == null)
                {
                    continue;
                }

                var otherTransform = prefab.Links[link].InstanceTarget as Transform;

                var otherTransformParent = otherTransform.parent;

                if (prefab.Links[otherTransformParent] == null || instance.Links[currentTransformParent] == null ||
                    prefab.Links[otherTransformParent].LIIF
                    != instance.Links[currentTransformParent].LIIF)
                {
                    _this.TransformParentChanges.Add(new PEModifications.HierarchyData {
                        child  = currentTransform,
                        parent = currentTransformParent
                    });
                }
            }
        }
 static internal IEnumerable <GameObject> GetPrefabsWithInstances(this PEPrefabScript _this)
 {
     return(PECache.Instance.GetPrefabsWithInstances(_this.PrefabGUID));
 }
        static internal void ApplyChanges(this PEPrefabScript _this, bool buildModifications = false)
        {
            if (!_this)
            {
                return;
            }

            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log(string.Format("[Begin Apply] {0}", _this.name));
            }

            EditorUtility.DisplayProgressBar("Apply changes", _this.name, 0f);

            if (buildModifications)
            {
                foreach (var pi in _this.GetComponentsInChildren <PEPrefabScript>(true))
                {
                    pi.BuildModifications();
                }
            }

            if (recursionCounter++ > 100)
            {
                Debug.LogError("Recursion");
                recursionCounter = 0;
                EditorUtility.ClearProgressBar();
                return;
            }

            _this.BuildLinks(true);
            _this.BuildModifications();

            var newPrefab = !AssetDatabase.Contains(_this.gameObject) ? PrefabUtility.ReplacePrefab(_this.gameObject, _this.Prefab, ReplacePrefabOptions.ConnectToPrefab) : _this.gameObject;

            var prefabs = _this.GetPrefabsWithInstances();

            foreach (var prefab in prefabs)
            {
                if (PEPrefs.DebugLevel > 0)
                {
                    Debug.Log("[Apply] Found Nested instance:" + prefab.name);
                }

                var instantiatedPrefabsList = new List <GameObject>();
                var instances = new List <PEPrefabScript>();
                if (prefab == null)
                {
                    continue;
                }

                var pi = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
                PrefabUtility.DisconnectPrefabInstance(pi);
                var nestedInstances = PEUtils.GetNestedInstances(pi).Where(p => p.PrefabGUID == _this.PrefabGUID && p.enabled).ToArray();

                instances.AddRange(nestedInstances);

                var rootInstance = pi.GetComponent <PEPrefabScript>();
                if (rootInstance && rootInstance.ParentPrefabGUID == _this.PrefabGUID)
                {
                    instances.Insert(0, rootInstance);
                }

                instantiatedPrefabsList.Add(pi);
                var counter = 0;

                foreach (var instance in instances)
                {
                    if (instance == null || instance.gameObject == null)
                    {
                        Debug.LogWarning("[Apply] Huston we have a problem. Prefab is destroyed before replace");
                        continue;
                    }

                    instantiatedPrefabsList.Remove(instance.gameObject);

                    var newObject = instance.ReplaceInPlace(newPrefab);

                    if (newObject == null || newObject.gameObject == null)
                    {
                        Debug.LogWarning("[Apply] Huston we have a problem. Prefab is destroyed after replace");
                        continue;
                    }

                    if (newObject.ParentPrefab == newPrefab)
                    {
                        instantiatedPrefabsList.Add(newObject.gameObject);
                    }

                    PrefabUtility.RecordPrefabInstancePropertyModifications(newObject);
                    EditorUtility.DisplayProgressBar("Apply changes", _this.name + " replaced in " + newObject.gameObject, ((float)counter++) / (float)instances.Count);
                }

                foreach (var instantiatedPrefab in instantiatedPrefabsList)
                {
                    if (instantiatedPrefab == null)
                    {
                        continue;
                    }

                    var instance = instantiatedPrefab.GetComponent <PEPrefabScript>();

                    if (instance)
                    {
                        instance.ApplyChanges();
                    }
                    else
                    {
                        PrefabUtility.ReplacePrefab(instantiatedPrefab, PrefabUtility.GetPrefabParent(instantiatedPrefab), ReplacePrefabOptions.ConnectToPrefab);
                    }

                    Object.DestroyImmediate(instantiatedPrefab);
                }
            }

            recursionCounter--;

            if (PEPrefs.DebugLevel > 0)
            {
                Debug.Log(string.Format("[End Apply] {0}", _this.name));
            }
        }
Beispiel #27
0
        static internal void BuildMenu(GenericMenu menu, PEPrefabScript prefabInstance, bool rootPrefab, string path = "", bool showParent = true, bool showInstances = true)
        {
            if (buildMenuRecursionList.Contains(prefabInstance.Prefab))
            {
                buildMenuRecursionList.AddLast(prefabInstance.Prefab);
                var prefabsArray = buildMenuRecursionList.Select(p => AssetDatabase.GetAssetPath(p)).ToArray();
                buildMenuRecursionList.Clear();
                throw new System.Exception("Prefab recursion detected:\n" + string.Join("\n", prefabsArray));
            }
            buildMenuRecursionList.AddLast(prefabInstance.Prefab);

            if (prefabInstance.ParentPrefab == null || !showParent)
            {
                menu.AddItem(new GUIContent(path + prefabInstance.Prefab.name), false, () =>
                {
                });
            }
            else
            {
                BuildMenu(menu, prefabInstance.ParentPrefab.GetComponent <PEPrefabScript>(), false, path + prefabInstance.Prefab.name + "/", true, false);
                menu.AddItem(new GUIContent(path + prefabInstance.Prefab.name), false, () =>
                {
                });
            }

            menu.AddSeparator(path + "");
            var isPrefab = prefabInstance.gameObject == prefabInstance.Prefab.gameObject;

            menu.AddItem(new GUIContent(path + "Select"), false, SelectPrefab, prefabInstance);

            var prefabType = PrefabUtility.GetPrefabType(prefabInstance.gameObject);
            var canApply   = rootPrefab && prefabType != PrefabType.ModelPrefab && prefabType != PrefabType.ModelPrefabInstance && prefabType != PrefabType.DisconnectedModelPrefabInstance;

            if (canApply)
            {
                menu.AddItem(new GUIContent(path + "Apply"), false, Apply, prefabInstance);
            }
            if (!AssetDatabase.Contains(prefabInstance) || !isPrefab)
            {
                menu.AddItem(new GUIContent(path + "Revert"), false, Revert, prefabInstance);

                if (prefabInstance.ParentPrefab != null)
                {
                    menu.AddItem(new GUIContent(path + "Revert To Parent"), false, RevertToParent, prefabInstance);
                }
            }
            menu.AddSeparator(path + "");
            menu.AddItem(new GUIContent(path + "Create Child"), false, CreateChild, prefabInstance);

                        #if INJECTION
            if (prefabInstance.ParentPrefab != null)
            {
                menu.AddItem(new GUIContent(path + "Insert Parent"), false, InjectParent, prefabInstance);
            }
                        #endif

            if (!rootPrefab && !AssetDatabase.Contains(prefabInstance))
            {
                menu.AddSeparator(path);
                if (prefabInstance.enabled)
                {
                    menu.AddItem(new GUIContent(path + "Disable"), false, obj => (obj as PEPrefabScript).enabled = false, prefabInstance);
                }
                else
                {
                    menu.AddItem(new GUIContent(path + "Enable"), false, obj => (obj as PEPrefabScript).enabled = true, prefabInstance);
                }
            }

            menu.AddSeparator(path);

            if (prefabInstance.GetPrefabsWithInstances().Any())
            {
                menu.AddItem(new GUIContent(path + "Instances/Select All Instances"), false, SelectInstances, prefabInstance);
            }
            if (showInstances)
            {
                foreach (var prefab in prefabInstance.GetPrefabsWithInstances())
                {
                    if (prefab == null)
                    {
                        continue;
                    }
                    var pi = prefab.GetComponent <PEPrefabScript>();

                    var name = prefab.name;

                    name = (pi != null && pi.ParentPrefab == prefabInstance.Prefab) ? "Child: " + name : "Contains in: " + name;


                    if (pi != null)
                    {
                        BuildMenu(menu, prefab.GetComponent <PEPrefabScript>(), false, path + "Instances/" + name + "/", false);
                    }

                    var current = prefab;
                    menu.AddItem(new GUIContent(path + "Instances/" + name), false, () =>
                    {
                        Selection.activeObject = current;
                    });
                }
            }

            menu.AddItem(new GUIContent(path + "Instantiate"), false,
                         pi => Selection.activeObject = PrefabUtility.InstantiatePrefab(((PEPrefabScript)pi).Prefab), prefabInstance);

            if (!AssetDatabase.Contains(prefabInstance))
            {
                menu.AddItem(new GUIContent(path + "Replace"), false, Replace, prefabInstance);
            }
            buildMenuRecursionList.Remove(prefabInstance.Prefab);
        }
Beispiel #28
0
        static void ApplyModifications(this PEPrefabScript _this, PEPrefabScript targetInstance)
        {
            targetInstance.Modifications = _this.Modifications;
            var modificatedList = new List <SerializedObject>();

            foreach (var modification in _this.Modifications.Modificated)
            {
                if (modification.Mode == PEModifications.PropertyData.PropertyMode.Ignore)
                {
                    continue;
                }

                if (modification.Object == null)
                {
                    continue;
                }

                var selfObject = new SerializedObject(modification.Object);

                var linkedObject = targetInstance.Links[modification.ObjeckLink];
                if (linkedObject == null || linkedObject.InstanceTarget == null)
                {
                    continue;
                }

                var targetObject = new SerializedObject(linkedObject.InstanceTarget);

                var selfProperty   = selfObject.FindProperty(modification.PropertyPath);
                var targetProperty = targetObject.FindProperty(modification.PropertyPath);

                if (targetProperty == null)
                {
                    Debug.Log("Property not found " + modification.PropertyPath);
                }
                else
                {
                    var target          = targetProperty.serializedObject.targetObject;
                    var propertyPath    = selfProperty.propertyPath;
                    var targetTransform = target as Transform;
                    if (propertyPath == "m_Father" && targetTransform)
                    {
                        PEUtils.SetParentAndSaveLocalTransform(targetTransform, selfProperty.objectReferenceValue as Transform);
                    }
                    else if (propertyPath == "m_RootOrder" && targetTransform)
                    {
                        targetTransform.SetSiblingIndex(selfProperty.intValue);
                    }
                    else
                    {
                        var value = selfProperty.GetPropertyValue();
                        if (selfProperty.propertyType == SerializedPropertyType.ObjectReference)
                        {
                            var selfValue = selfProperty.GetPropertyValue();

                            var selfLink   = _this.Links[selfValue as Object];
                            var targetLink = targetInstance.Links[selfLink];

                            if (targetLink != null)
                            {
                                value = targetLink.InstanceTarget;
                            }
                        }
                        targetProperty.SetPropertyValue(value);
                        targetObject.ApplyModifiedProperties();
                    }
                }
            }

            foreach (var po in modificatedList)
            {
                po.ApplyModifiedProperties();
            }
        }
Beispiel #29
0
		static void ApplyModifications(this PEPrefabScript _this, PEPrefabScript targetInstance)
		{
			targetInstance.Modifications = _this.Modifications;
			var modificatedList = new List<SerializedObject>();
			foreach (var modification in _this.Modifications.Modificated)
			{
				if (modification.Mode == PEModifications.PropertyData.PropertyMode.Ignore)
					continue;

				if (modification.Object == null)
					continue;

				var selfObject = new SerializedObject(modification.Object);

				var linkedObject = targetInstance.Links[modification.ObjeckLink];
				if (linkedObject == null || linkedObject.InstanceTarget == null)
					continue;

				var targetObject = new SerializedObject(linkedObject.InstanceTarget);

				var selfProperty = selfObject.FindProperty(modification.PropertyPath);
				var targetProperty = targetObject.FindProperty(modification.PropertyPath);

				if (targetProperty == null)
				{
					Debug.Log("Property not found " + modification.PropertyPath);
				}
				else
				{
					if (selfProperty.propertyPath.Contains("m_Father"))
					{
						PEUtils.SetParentAndSaveLocalTransform((targetProperty.serializedObject.targetObject as Transform), (selfProperty.GetPropertyValue() as Transform));
					}
					else
					{
						var value = selfProperty.GetPropertyValue();
						if (selfProperty.propertyType == SerializedPropertyType.ObjectReference)
						{
							var selfValue = selfProperty.GetPropertyValue();

							var selfLink = _this.Links[selfValue as Object];
							var targetLink = targetInstance.Links[selfLink];

							if (targetLink != null)
								value = targetLink.InstanceTarget;
						}
						targetProperty.SetPropertyValue(value);
						targetObject.ApplyModifiedProperties();
					}
				}
			}

			foreach (var po in modificatedList)
				po.ApplyModifiedProperties();
		}
        static void ApplyModifications(this PEPrefabScript _this, PEPrefabScript targetInstance)
        {
            targetInstance.Modifications = _this.Modifications;

            foreach (var modification in _this.Modifications.Modificated)
            {
                if (modification.Mode == PEModifications.PropertyData.PropertyMode.Ignore)
                {
                    continue;
                }

                if (modification.Object == null)
                {
                    continue;
                }

                var selfObject = new SerializedObject(modification.Object);

                var linkedObject = targetInstance.Links[modification.ObjeckLink];
                if (linkedObject == null || linkedObject.InstanceTarget == null)
                {
                    continue;
                }

                var targetObject = new SerializedObject(linkedObject.InstanceTarget);

                var selfProperty   = selfObject.FindProperty(modification.PropertyPath);
                var targetProperty = targetObject.FindProperty(modification.PropertyPath);

                if (targetProperty == null)
                {
                    Debug.Log("Property not found " + modification.PropertyPath);
                }
                else
                {
                    if (selfProperty.propertyType == SerializedPropertyType.ObjectReference)
                    {
                        var selfValue = selfProperty.GetPropertyValue();

                        var selfLink   = _this.Links[selfValue as Object];
                        var targetLink = targetInstance.Links[selfLink];

                        if (targetLink != null)
                        {
                            targetProperty.SetPropertyValue(targetLink.InstanceTarget);
                        }
                        else
                        {
                            targetProperty.SetPropertyValue(selfProperty.GetPropertyValue());
                        }
                    }
                    else
                    {
                        targetProperty.SetPropertyValue(selfProperty.GetPropertyValue());
                    }

                    targetObject.ApplyModifiedProperties();
                    //In some cases unity can destroy prev object, just fix runtime references...
                    linkedObject.InstanceTarget = targetObject.targetObject;
                }
            }
        }
Beispiel #31
0
	static internal void DrawView(PEPrefabScript script)
	{
		GUILayout.Space(3);
		var icon = EditorGUIUtility.ObjectContent(null, typeof(GameObject));
		GUILayout.BeginHorizontal();

		if (!string.IsNullOrEmpty(script.ParentPrefabGUID))
		{
			var c = GUI.backgroundColor;

			if (!script.ParentPrefab)
				GUI.backgroundColor = Color.red;

			var content = new GUIContent(script.ParentPrefab ? script.ParentPrefab.name : "Missing:" + script.ParentPrefabGUID, icon.image);

			GUILayout.Label("Parent:", GUILayout.Width(50));

			if (GUILayout.Button(content, EditorStyles.miniButton, GUILayout.Height(16), GUILayout.MinWidth(0)))
				EditorGUIUtility.PingObject(script.ParentPrefab);

			GUI.backgroundColor = c;
		}
		if (!string.IsNullOrEmpty(script.PrefabGUID))
		{
			var c = GUI.backgroundColor;

			if (!script.Prefab)
				GUI.backgroundColor = Color.red;

			var content = new GUIContent(script.Prefab ? script.Prefab.name : "Missing:" + script.PrefabGUID, icon.image);

			GUILayout.Label("Prefab:", GUILayout.Width(50));

			if (GUILayout.Button(content, EditorStyles.miniButton, GUILayout.Height(16), GUILayout.MinWidth(0)))
				EditorGUIUtility.PingObject(script.Prefab);

			GUI.backgroundColor = c;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(1);
		DrawCommands(script);

		EditorGUIUtility.labelWidth = 150;		
	}
 static internal bool IsNonPrefabObject(this PEPrefabScript _this, Object obj)
 {
     return(_this.Links[obj] == null);
 }
Beispiel #33
0
	static void DrawCommands(PEPrefabScript prefabScript)
	{
		var e = GUI.enabled;
		GUI.enabled = true;
		if (GUILayout.Button("Menu", EditorStyles.miniButton))
		{
			var menu = new GenericMenu();
			PEUtils.BuildMenu(menu, prefabScript, PrefabUtility.GetPrefabParent(prefabScript.gameObject) == prefabScript.Prefab);
			menu.ShowAsContext();
		}
		GUI.enabled = e;
	}
		static void ApplyModifications(this PEPrefabScript _this, PEPrefabScript targetInstance)
		{
			targetInstance.Modifications = _this.Modifications;
			var modificatedList = new List<SerializedObject>();

			foreach (var modification in _this.Modifications.Modificated)
			{
				if (modification.Mode == PEModifications.PropertyData.PropertyMode.Ignore)
					continue;

				if (modification.Object == null)
					continue;

				var selfObject = new SerializedObject(modification.Object);

				var linkedObject = targetInstance.Links[modification.ObjeckLink];
				if (linkedObject == null || linkedObject.InstanceTarget == null)
					continue;

				var targetObject = new SerializedObject(linkedObject.InstanceTarget);

				var selfProperty = selfObject.FindProperty(modification.PropertyPath);
				var targetProperty = targetObject.FindProperty(modification.PropertyPath);

				if (targetProperty == null)
				{
					Debug.Log("Property not found " + modification.PropertyPath);
				}
				else
				{
					var value = selfProperty.GetPropertyValue();
					if (selfProperty.propertyType == SerializedPropertyType.ObjectReference)
					{
						var selfValue = selfProperty.GetPropertyValue();

						var selfLink = _this.Links[selfValue as Object];
						var targetLink = targetInstance.Links[selfLink];

						if (targetLink != null)
							value = targetLink.InstanceTarget;
					}
					targetProperty.SetPropertyValue(value);

					targetObject.ApplyModifiedProperties();
					//In some cases unity can destroy prev object, just fix runtime references...
					linkedObject.InstanceTarget = targetObject.targetObject; 
				}
			}

			foreach (var po in modificatedList)
				po.ApplyModifiedProperties();
		}
        static internal void GetProperties(this PEModifications.PropertyData _this, out SerializedProperty prefabProperty, out SerializedProperty objectProperty, PEPrefabScript script)
        {
            var couple = _this.UserData as PropertyCouple;

            if (couple == null)
            {
                couple = new PropertyCouple();
                if (couple.objectProperty == null)
                {
                    var so = new SerializedObject(_this.Object);

                    if (so != null)
                    {
                        couple.objectProperty = so.FindProperty(_this.PropertyPath);
                    }

                    if (couple.objectProperty == null)
                    {
                        if (PEPrefs.DebugLevel > 0)
                        {
                            Debug.Log(string.Format("Property {0} not found on Object {1}", _this.PropertyPath, _this.Object));
                        }
                    }
                }

                if (couple.prefabProperty == null)
                {
                    var prefabObject = script.Links.GetPrefabObject(script.GetDiffWith().gameObject, _this.Object);

                    if (prefabObject != null)
                    {
                        var so = new SerializedObject(prefabObject);
                        if (so != null)
                        {
                            couple.prefabProperty = so.FindProperty(_this.PropertyPath);
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Prefab object for prefab property modifications is not found");
                    }
                }
            }

            prefabProperty = couple.prefabProperty;
            objectProperty = couple.objectProperty;
            _this.UserData = couple;
        }