/// <summary> /// Clones the object original, places it at position and sets the rotation to rotation, then returns the cloned object. /// This is essentially the same as using duplicate command (cmd-d) in Unity and then moving the object to the given location. /// If a game object, component or script instance is passed, Instantiate will clone the entire game object hierarchy, with all children cloned as well. /// All game objects are activated. /// </summary> /// <param name="original"></param> public static UnityObject Instantiate(UnityObject original) { if (original == null) { return(null); } GameObject clone = null; if (original is Component) { clone = (original as Component).gameObject.Clone() as GameObject; } else if (original is GameObject) { GameObject toClone = (original as GameObject).transform.root.gameObject; //GameObject toClone = original as GameObject; clone = toClone.Clone() as GameObject; } else { return(original.Clone()); } // NOTE: It is very important that this is done at the end otherwise we cannot find the correct object to return. Dictionary <int, UnityObject> idMap = new Dictionary <int, UnityObject>(); clone.SetNewId(idMap); clone.FixReferences(idMap); Application.RegisterComponents(newInstantiatedComponents); Application.AwakeNewComponents(); return(idMap[original.GetInstanceID()]); }
public void TrackEvent(UnityObject obj, string eventName) { if (trackedInstances.Contains(obj.GetInstanceID())) { Debug.Log("Lifecycle event: " + eventName + " for " + obj); } }
private void DoFixReferences(object objectToFix, Dictionary <int, UnityObject> idMap) { List <FieldInfo> memInfo = GetMembersToFix(objectToFix.GetType()); for (int i = 0; i < memInfo.Count; i++) { FieldInfo field = memInfo[i]; if (typeof(UnityObject).IsAssignableFrom(memInfo[i].FieldType)) { UnityObject val = (field.GetValue(objectToFix) as UnityObject); if (val == null || (val is Asset)) { continue; } if (idMap.ContainsKey(val.GetInstanceID())) { if (val != idMap[val.GetInstanceID()]) { field.SetValue(objectToFix, idMap[val.GetInstanceID()]); } } } if (typeof(IList).IsAssignableFrom(field.FieldType)) { if (field.FieldType.HasElementType && !field.FieldType.GetElementType().IsSubclassOf(typeof(UnityObject))) { continue; } IList list = (memInfo[i].GetValue(objectToFix) as IList); if (list != null) { IList newList; if (list is Array) { newList = (IList)(list as Array).Clone(); } else { ConstructorInfo ctor = list.GetType().GetConstructor(new Type[] { typeof(int) }); newList = (IList)ctor.Invoke(new object[] { list.Count }); } for (int j = 0; j < list.Count; j++) { if (!(newList is Array)) { newList.Add(list[j]); } if (list[j] is UnityObject && !(list[j] is Asset)) { if (idMap.ContainsKey((list[j] as UnityObject).GetInstanceID())) { newList[j] = idMap[(list[j] as UnityObject).GetInstanceID()]; } } } memInfo[i].SetValue(objectToFix, newList); } } if (Application.typeCaps.HasCaps(memInfo[i].FieldType, TypeSet.TypeCapabilities.FixReferences)) { DoFixReferences(memInfo[i].GetValue(objectToFix), idMap); } } }
internal static void CleanUp() { while (markedForDestruction.Count > 0) { UnityObject obj = markedForDestruction.Dequeue(); objects.Remove(obj.GetInstanceID()); if (obj is GameObject) { (obj as GameObject).DoDestroy(); } Component cmp = (obj as Component); if (cmp != null) { if (cmp is Renderer) { Camera.RemoveRenderer(cmp as Renderer); } if (cmp is Camera) { Camera.RemoveCamera(cmp as Camera); } if (cmp.gameObject != null) { cmp.gameObject.RemoveComponent(cmp); } if (cmp is PressPlay.FFWD.Interfaces.IUpdateable) { PressPlay.FFWD.Interfaces.IUpdateable upd = cmp as PressPlay.FFWD.Interfaces.IUpdateable; if (updateComponents.Contains(upd)) { updateComponents.Remove(upd); } if (lateUpdateComponents.Contains(upd)) { lateUpdateComponents.Remove(upd); } } if (cmp is IFixedUpdateable) { if (fixedUpdateComponents.Contains(cmp as IFixedUpdateable)) { fixedUpdateComponents.Remove(cmp as IFixedUpdateable); } } if (cmp is MonoBehaviour) { if (guiComponents.Contains(cmp as MonoBehaviour)) { guiComponents.Remove(cmp as MonoBehaviour); } } for (int j = invokeCalls.Count - 1; j >= 0; j--) { if (invokeCalls[j].behaviour == cmp) { invokeCalls.RemoveAt(j); } } } } }