Example #1
0
        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);
            }
        }
Example #4
0
        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);
        }