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 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(); } }