private static void CollectAssetReferncesForComponent(Component comp, Dictionary <Component, Component2MeshAndMaterials> propRefereces) { SerializedObject srcSO = new SerializedObject(comp); SerializedProperty prop = srcSO.GetIterator(); List <Prop2Reference> propRefs = new List <Prop2Reference>(); if (prop.NextVisible(true)) { do { // If is an internal reference // Or is a reference to a mesh or material that is different. if (prop.propertyType == SerializedPropertyType.ObjectReference) { if (!IsSceneInstanceAsset(prop.objectReferenceValue)) { // mesh to materials Prop2Reference srcComp2Mats = new Prop2Reference() { propertyName = prop.propertyPath, overriddenInSrcInstance = prop.prefabOverride, obj = prop.objectReferenceValue, }; propRefs.Add(srcComp2Mats); } } }while (prop.NextVisible(true)); } if (propRefs.Count > 0) { Component2MeshAndMaterials srcComp2Mats = new Component2MeshAndMaterials() { component = comp, props = propRefs, }; propRefereces.Add(srcComp2Mats.component, srcComp2Mats); } }
private bool CopyGameObjectDifferences(GameObject srcGO, GameObject targGO, Dictionary <UnityEngine.Object, UnityEngine.Object> src2targetObjMap, Dictionary <Component, Component2MeshAndMaterials> component2MeshAndMats) { Component[] srcComps = srcGO.GetComponents <Component>(); Component[] targComps = targGO.GetComponents <Component>(); if (srcComps.Length != targComps.Length) { AddError(srcGO, "Source GameObject had a different number of components than target."); return(false); } for (int i = 0; i < srcComps.Length; i++) { if (srcComps[i].GetType() == targComps[i].GetType()) { List <Prop2Reference> targetInernalRefs = new List <Prop2Reference>(); SerializedObject serializedObject = new SerializedObject(targComps[i]); // Go through target and find all references, check if these are refs to internal gameObjects/components of the prefab // snapshot all internal refs. { SerializedProperty arrayPropParent = null; SerializedProperty prop = serializedObject.GetIterator(); if (prop.NextVisible(true)) { do { // Get some info about the array if this is an element of an array. string parentArrayPath; int parentArraySize; if (arrayPropParent != null && prop.propertyPath.StartsWith(arrayPropParent.propertyPath + ".Array.data[")) { parentArrayPath = arrayPropParent.propertyPath; parentArraySize = arrayPropParent.arraySize; } else { parentArrayPath = ""; parentArraySize = -1; } // If is an internal reference // Or is a reference to a mesh or material that is different. if (prop.propertyType == SerializedPropertyType.ObjectReference && src2targetObjMap.ContainsValue(prop.objectReferenceValue)) { Prop2Reference p2r = new Prop2Reference() { propertyName = prop.propertyPath, obj = prop.objectReferenceValue, parentArrayName = parentArrayPath, parentArraySize = parentArraySize, }; targetInernalRefs.Add(p2r); } }while (prop.NextVisible(true)); } } EditorUtility.CopySerializedIfDifferent(srcComps[i], targComps[i]); serializedObject.Update(); // Restore internal references. for (int refIdx = 0; refIdx < targetInernalRefs.Count; refIdx++) { Prop2Reference p2r = targetInernalRefs[refIdx]; SerializedProperty sp = serializedObject.FindProperty(p2r.propertyName); sp.objectReferenceValue = targetInernalRefs[refIdx].obj; // The copy may have resized arrays. Restore the array size from the prefab. if (p2r.parentArraySize != -1) { sp = serializedObject.FindProperty(p2r.parentArrayName); sp.arraySize = p2r.parentArraySize; } } // Restore references to project assets // Don't restore renderer assets because these are materials and go with the meshes. { if (component2MeshAndMats.ContainsKey(targComps[i])) { Component2MeshAndMaterials meshAndMats = component2MeshAndMats[targComps[i]]; SerializedObject targSO = new SerializedObject(meshAndMats.component); for (int prpIdx = 0; prpIdx < meshAndMats.props.Count; prpIdx++) { Prop2Reference p2r = meshAndMats.props[prpIdx]; SerializedProperty prop = targSO.FindProperty(p2r.propertyName); Debug.Log("Restoring asset refs for component " + targComps[i] + " nm " + prop.name + " parentArray " + p2r.parentArrayName + " arraySize" + p2r.parentArraySize); prop.objectReferenceValue = meshAndMats.props[prpIdx].obj; // The copy may have resized arrays. Restore the array size from the prefab. if (p2r.parentArraySize != -1) { prop = targSO.FindProperty(p2r.parentArrayName); prop.arraySize = p2r.parentArraySize; } } targSO.ApplyModifiedPropertiesWithoutUndo(); } } serializedObject.ApplyModifiedProperties(); } else { AddError(srcGO, "Components did not match"); return(false); } } return(true); }
private static void CollectAssetReferncesForComponent(Component comp, Dictionary <Component, Component2MeshAndMaterials> propRefereces, bool log = false) { SerializedObject srcSO = new SerializedObject(comp); SerializedProperty prop = srcSO.GetIterator(); List <Prop2Reference> propRefs = new List <Prop2Reference>(); SerializedProperty arrayPropParent = null; if (prop.NextVisible(true)) { do { if (log && prop.isArray) { Debug.Log("Found Array prop: " + prop.propertyPath + " size: " + prop.arraySize); } if (prop.isArray) { arrayPropParent = srcSO.FindProperty(prop.propertyPath); } // If is an internal reference // Or is a reference to a mesh or material that is different. if (prop.propertyType == SerializedPropertyType.ObjectReference) { if (!IsSceneInstanceAsset(prop.objectReferenceValue)) { if (log) { Debug.Log("Visiting coponent " + comp + " propName: " + prop.name + " propPath: " + prop.propertyPath + " isArray: " + prop.isArray); } // Get some info about the array if this is an element of an array. string parentArrayPath; int parentArraySize; if (arrayPropParent != null && prop.propertyPath.StartsWith(arrayPropParent.propertyPath + ".Array.data[")) { parentArrayPath = arrayPropParent.propertyPath; parentArraySize = arrayPropParent.arraySize; } else { parentArrayPath = ""; parentArraySize = -1; } // mesh to materials Prop2Reference srcComp2Mats = new Prop2Reference() { propertyName = prop.propertyPath, overriddenInSrcInstance = prop.prefabOverride, obj = prop.objectReferenceValue, parentArrayName = parentArrayPath, parentArraySize = parentArraySize, }; propRefs.Add(srcComp2Mats); } } }while (prop.NextVisible(true)); } if (propRefs.Count > 0) { Component2MeshAndMaterials srcComp2Mats = new Component2MeshAndMaterials() { component = comp, props = propRefs, }; propRefereces.Add(srcComp2Mats.component, srcComp2Mats); } }
private bool CopyGameObjectDifferences(GameObject srcGO, GameObject targGO, Dictionary <UnityEngine.Object, UnityEngine.Object> src2targetObjMap, Dictionary <Component, Component2MeshAndMaterials> component2MeshAndMats) { Component[] srcComps = srcGO.GetComponents <Component>(); Component[] targComps = targGO.GetComponents <Component>(); if (srcComps.Length != targComps.Length) { AddError(srcGO, "Source GameObject had a different number of components than target."); return(false); } for (int i = 0; i < srcComps.Length; i++) { if (srcComps[i].GetType() == targComps[i].GetType()) { List <Prop2Reference> targetInernalRefs = new List <Prop2Reference>(); SerializedObject serializedObject = new SerializedObject(targComps[i]); // Go through target and find all references, check if these are refs to internal gameObjects/components of the prefab // snapshot all internal refs. SerializedProperty prop = serializedObject.GetIterator(); if (prop.NextVisible(true)) { do { // If is an internal reference // Or is a reference to a mesh or material that is different. if (prop.propertyType == SerializedPropertyType.ObjectReference && src2targetObjMap.ContainsValue(prop.objectReferenceValue)) { Prop2Reference p2r = new Prop2Reference() { propertyName = prop.propertyPath, obj = prop.objectReferenceValue, }; targetInernalRefs.Add(p2r); } }while (prop.NextVisible(true)); } EditorUtility.CopySerializedIfDifferent(srcComps[i], targComps[i]); serializedObject.Update(); // Restore internal references. for (int refIdx = 0; refIdx < targetInernalRefs.Count; refIdx++) { SerializedProperty sp = serializedObject.FindProperty(targetInernalRefs[refIdx].propertyName); sp.objectReferenceValue = targetInernalRefs[refIdx].obj; //Debug.Log("Comp" + targComps[i] + " RestoringProp: " + targetInernalRefs[refIdx].propertyName + " val " + targetInernalRefs[refIdx].obj); } // Restore references to project assets if (component2MeshAndMats.ContainsKey(targComps[i])) { Component2MeshAndMaterials meshAndMats = component2MeshAndMats[targComps[i]]; SerializedObject targSO = new SerializedObject(meshAndMats.component); for (int prpIdx = 0; prpIdx < meshAndMats.props.Count; prpIdx++) { prop = targSO.FindProperty(meshAndMats.props[prpIdx].propertyName); prop.objectReferenceValue = meshAndMats.props[prpIdx].obj; } targSO.ApplyModifiedPropertiesWithoutUndo(); } serializedObject.ApplyModifiedProperties(); } else { AddError(srcGO, "Components did not match"); return(false); } } return(true); }