private static bool DestroyGameObjects(Transform t, bool forceDestroy) { //We going to destroy all gameObjects except PersistentIgnore bool destroy = true; //destroy by default if (!forceDestroy) //if not forced to destroy { PersistentIgnore ignore = t.GetComponent <PersistentIgnore>(); if (ignore) //check if this is PersistentIgnore { if (ignore.IsRuntime) { //if PersistentIgnore created in runtime (not in UnityEditor) then destroy it return(true); } return(false); /* * if (ignore.ReplacementPrefab == null) * { * //if there is no replacement prefab leave gameobject subtree as is and do not destroy nothing * return false; * } * * //if ReplacementPrefab field set do not destroy GameObject * destroy = false; * //but force destory all it's children * forceDestroy = true; */ } } List <Transform> children = new List <Transform>(); foreach (Transform child in t) { children.Add(child); } for (int i = 0; i < children.Count; ++i) { Transform child = children[i]; if (DestroyGameObjects(child, forceDestroy)) { UnityObject.DestroyImmediate(child.gameObject); } else { //PersistentIgnore objects became roots to prevent destruction child.SetParent(null, true); } } return(destroy); }
/// <summary> /// Create Persistent Data for all GameObjects and Components, write it to PersistentData list /// </summary> /// <param name="go">gameObject (initially root)</param> /// <param name="data">list which will be populated with PersistentData objects</param> private static void CreatePersistentData(GameObject go, List <PersistentData> data) { PersistentIgnore persistentIgnore = go.GetComponent <PersistentIgnore>(); if (persistentIgnore != null /* && persistentIgnore.ReplacementPrefab == null*/) { //Do not save persistent ignore objects without replacement prefab return; } PersistentData goData = Create(go); if (goData != null) { goData.ActiveSelf = go.activeSelf; goData.ReadFrom(go); data.Add(goData); } Component[] components; if (persistentIgnore == null) { components = go.GetComponents <Component>().Where(c => c != null && !PersistentDescriptor.IgnoreTypes.Contains(c.GetType())).ToArray(); } else { //if PersistentIgnore component exists save only Transform and PersistentIgnore components components = go.GetComponents <Transform>(); Array.Resize(ref components, components.Length + 1); components[components.Length - 1] = persistentIgnore; } for (int i = 0; i < components.Length; ++i) { Component component = components[i]; PersistentData componentData = PersistentData.Create(component); if (componentData != null) { componentData.ReadFrom(component); data.Add(componentData); } } Transform transform = go.transform; foreach (Transform childTransform in transform) { //Do not create childDescriptor for replacementPrefab child & for persistentIgnore without ReplacementPrefab if (persistentIgnore == null /* || persistentIgnore.ReplacementPrefab != null && !persistentIgnore.IsChildOfReplacementPrefab(childTransform)*/) { //only for independent child CreatePersistentData(childTransform.gameObject, data); } } }
private static void FindPersistentIgnoreObjects(Transform t, List <UnityObject> pIgnoreObjects) { PersistentIgnore pIgnore = t.GetComponent <PersistentIgnore>(); if (pIgnore != null) { pIgnoreObjects.Add(pIgnore); } foreach (Transform c in t) { FindPersistentIgnoreObjects(c, pIgnoreObjects); } }
private static void CreatePersistentIngoreResourceGroups(ResourceMap map, List <UnityObject> ignoreObjects, Dictionary <UnityObject, int> dict) { for (int i = 0; i < ignoreObjects.Count; ++i) { PersistentIgnore io = (PersistentIgnore)ignoreObjects[i]; if (!io) { continue; } GameObject go = io.gameObject; Transform tr = io.transform; ResourceGroup[] resourceGroups = go.GetComponents <ResourceGroup>(); foreach (ResourceGroup rg in resourceGroups) { UnityObject.DestroyImmediate(rg); } List <ObjectToID> mappingsInGroup = new List <ObjectToID>(); ResourceGroup resourceGroup = go.AddComponent <ResourceGroup>(); resourceGroup.Guid = map.Guid; int id; if (!dict.TryGetValue(io, out id)) { id = map.IncCounter(); dict.Add(io, id); } mappingsInGroup.Add(new ObjectToID(io, id)); if (!dict.TryGetValue(go, out id)) { id = map.IncCounter(); dict.Add(go, id); } mappingsInGroup.Add(new ObjectToID(go, id)); if (!dict.TryGetValue(tr, out id)) { id = map.IncCounter(); dict.Add(tr, id); } mappingsInGroup.Add(new ObjectToID(tr, id)); resourceGroup.Mapping = mappingsInGroup.OrderBy(m => m.Name).ToArray(); } }
public static GameObject InstantiatePrefab(this GameObject prefab, Vector3 position, Quaternion rotation) { if (prefab == null) { return(null); } PersistentIgnore persistentIgnore = prefab.GetComponent <PersistentIgnore>(); if (persistentIgnore != null) { return(persistentIgnore.InstantiatePrefab(prefab, position, rotation)); } return(UnityObject.Instantiate(prefab, position, rotation)); }
private void LoadMappings(ResourceGroup group, bool ignoreConflicts = false, List <int> ids = null) { if (!group.gameObject.IsPrefab()) { PersistentIgnore ignore = group.GetComponent <PersistentIgnore>(); if (ignore == null || ignore.IsRuntime) { return; } } ObjectToID[] mappings = group.Mapping; for (int j = 0; j < mappings.Length; ++j) { ObjectToID mapping = mappings[j]; if (mapping.Object == null) { continue; } int realId = mapping.Object.GetInstanceID(); if (m_idToId.ContainsKey(realId)) { if (ignoreConflicts) { continue; } Debug.LogError("key " + realId + "already added. Group " + group.name + " guid " + group.Guid + " mapping " + j + " mapped object " + mapping.Object); } m_idToId.Add(realId, mapping.Id); if (ids != null) { //ss ids.Add(realId); } } }
public static void RestoreDataAndResolveDependencies(PersistentData[] dataObjects, Dictionary <long, UnityObject> objects) { //3. Create persistent data dictionary (new object id -> Persistent Data) Dictionary <UnityObject, PersistentData> persistentData = new Dictionary <UnityObject, PersistentData>(); for (int i = 0; i < dataObjects.Length; ++i) { PersistentData data = dataObjects[i]; UnityObject obj; if (objects.TryGetValue(data.InstanceId, out obj)) { persistentData.Add(obj, data); } } //4. Create replacement prefabs and replace PersistentIgnoreObjects foreach (KeyValuePair <UnityObject, PersistentData> kvp in persistentData) { PersistentIgnore persistentIgnore = kvp.Key as PersistentIgnore; if (persistentIgnore == null) { continue; } GameObject go = persistentIgnore.gameObject; PersistentData goData = persistentData[go]; PersistentData scriptData = kvp.Value; PersistentData transformData = persistentData[go.transform]; //Recover go data goData.WriteTo(go, objects); //Recover script data scriptData.WriteTo(persistentIgnore, objects); //Recover transform data transformData.WriteTo(go.transform, objects); /* * if (persistentIgnore.ReplacementPrefab != null) * { * //make sure that Replacement prefab is not active, * //this will prevent Awake and other methods from running too early * persistentIgnore.ReplacementPrefab.gameObject.SetActive(false); * * PersistentIgnore replacementScript = UnityObject.Instantiate(persistentIgnore.ReplacementPrefab); * List<GameObject> destroy = new List<GameObject>(); * //Destroy prefab children according to PersistentIgnore component settings * foreach (Transform childTransform in replacementScript.transform) * { * if (!replacementScript.IsChildOfReplacementPrefab(childTransform)) * { * destroy.Add(childTransform.gameObject); * } * } * for (int i = 0; i < destroy.Count; ++i) * { * UnityObject.DestroyImmediate(destroy[i]); * } * * //replace gameObject with repacementPrefab in objects dictionary * //Thereby all other objects will reference replacementPrefab instad of gameObject * objects[goData.InstanceId] = replacementScript.gameObject; * objects[scriptData.InstanceId] = replacementScript; * objects[transformData.InstanceId] = replacementScript.transform; * * //insert replacementPrefab to hierarchy * replacementScript.transform.SetParent(go.transform.parent); * foreach (Transform childTransform in go.transform) * { * childTransform.SetParent(replacementScript.transform); * } * * UnityObject.Destroy(go); //Destroy gameObject which was replaced by replacement Prefab * } */ } List <GameObject> goList = new List <GameObject>(); List <bool> goActivationList = new List <bool>(); //5. Recover data using scene.Data for (int i = 0; i < dataObjects.Length; ++i) { PersistentData data = dataObjects[i]; if (!objects.ContainsKey(data.InstanceId)) { Debug.LogWarningFormat("objects does not have object with instance id {0} however PersistentData of type {1} is present", data.InstanceId, data.GetType()); continue; } UnityObject obj = objects[data.InstanceId]; data.WriteTo(obj, objects); if (obj is GameObject) { goList.Add((GameObject)obj); goActivationList.Add(data.ActiveSelf); } } for (int i = 0; i < goList.Count; ++i) { bool activeSelf = goActivationList[i]; GameObject go = goList[i]; go.SetActive(activeSelf); } }
/// <summary> /// Create PersistentDescriptor for gameObject recursive. Set PersistentDescriptor.Parent. /// Used is process of creation of PersistentScene object for current scene /// </summary> /// <param name="go">gameObject (initally root gameObject)</param> /// <param name="parentDescriptor">parent descriptor (initially null)</param> /// <returns></returns> public static PersistentDescriptor CreateDescriptor(GameObject go, PersistentDescriptor parentDescriptor = null) { PersistentIgnore persistentIgnore = go.GetComponent <PersistentIgnore>(); if (persistentIgnore != null /*&& persistentIgnore.ReplacementPrefab == null*/) { //Do not save persistent ignore objects without replacement prefab return(null); } PersistentDescriptor descriptor = new PersistentDescriptor(go); descriptor.Parent = parentDescriptor; Component[] components; if (persistentIgnore == null) { components = go.GetComponents <Component>().Where(c => c != null && !IgnoreTypes.Contains(c.GetType())).ToArray(); } else { //if PersistentIgnore component exists then save only Transform and PersistentIgnore components components = go.GetComponents <Transform>(); Array.Resize(ref components, components.Length + 1); components[components.Length - 1] = persistentIgnore; } if (components.Length > 0) { descriptor.Components = new PersistentDescriptor[components.Length]; for (int i = 0; i < components.Length; ++i) { Component component = components[i]; PersistentDescriptor componentDescriptor = new PersistentDescriptor(component); componentDescriptor.Parent = descriptor; descriptor.Components[i] = componentDescriptor; } } Transform transform = go.transform; if (transform.childCount > 0) { List <PersistentDescriptor> children = new List <PersistentDescriptor>(); foreach (Transform child in transform) { //Do not create childDescriptor for replacementPrefab child & for persistentIgnore without ReplacementPrefab if (persistentIgnore == null /* || persistentIgnore.ReplacementPrefab != null && !persistentIgnore.IsChildOfReplacementPrefab(child)*/) { //only for independent child PersistentDescriptor childDescriptor = CreateDescriptor(child.gameObject, descriptor); if (childDescriptor != null) { children.Add(childDescriptor); } } } descriptor.Children = children.ToArray(); } return(descriptor); }