#if UNITY_EDITOR using UnityEngine; using System.Collections.Generic; namespace O3DWB { public static class ObjectErase { #region Public Static Functions public static void EraseGameObjectCollection(List gameObjectsToErase) { List objectsToErase = GetGameObjectsWhichCanBeErased(gameObjectsToErase); PrepareGameObjectCollectionForEraseOperation(objectsToErase); foreach (GameObject gameObject in objectsToErase) EraseGameObject(gameObject); } public static void EraseObjectHierarchiesInObjectCollection(List gameObjectsToErase) { HashSet rootsToErase = new HashSet(Octave3DWorldBuilder.ActiveInstance.GetRoots(gameObjectsToErase)); List objectsToErase = GetGameObjectsWhichCanBeErased(rootsToErase); PrepareGameObjectCollectionForEraseOperation(objectsToErase); foreach (GameObject gameObject in objectsToErase) EraseEntireGameObjectHierarchy(gameObject); } public static void EraseEntireGameObjectHierarchy(GameObject gameObject) { if (!CanGameObjectBeErased(gameObject)) return; ObjectEraserSettings eraserSettings = ObjectEraserSettings.Get(); GameObject root = Octave3DWorldBuilder.ActiveInstance.GetRoot(gameObject); if (root != null) DestroyGameObject(root, eraserSettings.AllowUndoRedo); } public static void EraseGameObject(GameObject gameObject) { if (!CanGameObjectBeErased(gameObject)) return; // This function is buggy - it no longer works with newer versions of Unity // because erasing children in an object hierarchy is no longer allowed. Moving // children from one parent to another is also now restricted. ObjectEraserSettings eraserSettings = ObjectEraserSettings.Get(); bool isPivotWorkingObject = Octave3DWorldBuilder.ActiveInstance.IsPivotWorkingObject(gameObject); if (isPivotWorkingObject) { List immediateChildren = gameObject.GetImmediateChildren(); gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo); DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo); for (int childIndex = 0; childIndex < immediateChildren.Count; ++childIndex) { if (ObjectQueries.IsGameObjectHierarchyEmpty(immediateChildren[childIndex])) DestroyGameObject(immediateChildren[childIndex], eraserSettings.AllowUndoRedo); } } else { GameObject root = Octave3DWorldBuilder.ActiveInstance.GetRoot(gameObject); if (root == gameObject) { List immediateChildren = gameObject.GetImmediateChildren(); gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo); DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo); foreach(GameObject child in immediateChildren) { if (ObjectQueries.IsGameObjectHierarchyEmpty(child)) DestroyGameObject(child, eraserSettings.AllowUndoRedo); } } else { GameObject immediateParent = gameObject.transform.parent.gameObject; gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo); DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo); if (ObjectQueries.IsGameObjectHierarchyEmpty(root) && CanGameObjectBeErased(root)) DestroyGameObject(root, eraserSettings.AllowUndoRedo); else if (immediateParent.transform.childCount == 0 && ObjectQueries.IsGameObjectEmpty(immediateParent) && !Octave3DWorldBuilder.ActiveInstance.IsPivotWorkingObject(immediateParent)) DestroyGameObject(immediateParent, eraserSettings.AllowUndoRedo); } } } public static bool CanGameObjectBeErased(GameObject gameObject) { if (gameObject == null) return false; return ObjectQueries.CanGameObjectBeInteractedWith(gameObject) && !ObjectEraser.Get().EraseMask.IsGameObjectMasked(gameObject); } #endregion #region Private Static Functions private static void DestroyGameObject(GameObject gameObject, bool allowUndoRedo) { if (allowUndoRedo) UndoEx.DestroyObjectImmediate(gameObject); else Octave3DWorldBuilder.DestroyImmediate(gameObject); } private static List GetGameObjectsWhichCanBeErased(IEnumerable gameObjects) { var objectsWhichCanBeErased = new List(); foreach (GameObject gameObject in gameObjects) { if (CanGameObjectBeErased(gameObject)) objectsWhichCanBeErased.Add(gameObject); } return objectsWhichCanBeErased; } private static void PrepareGameObjectCollectionForEraseOperation(IEnumerable gameObjects) { ObjectSelection objectSelection = ObjectSelection.Get(); // Note: Before objects are erased, we have to remove them from the object selection. // Otherwise, the selection information will be lost when performing an Undo // operation. I can't figure out why this is :). foreach (GameObject gameObject in gameObjects) { objectSelection.RemoveGameObjectFromSelection(gameObject); } } #endregion } } #endif