ObjectErase.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. namespace O3DWB
  5. {
  6. public static class ObjectErase
  7. {
  8. #region Public Static Functions
  9. public static void EraseGameObjectCollection(List<GameObject> gameObjectsToErase)
  10. {
  11. List<GameObject> objectsToErase = GetGameObjectsWhichCanBeErased(gameObjectsToErase);
  12. PrepareGameObjectCollectionForEraseOperation(objectsToErase);
  13. foreach (GameObject gameObject in objectsToErase) EraseGameObject(gameObject);
  14. }
  15. public static void EraseObjectHierarchiesInObjectCollection(List<GameObject> gameObjectsToErase)
  16. {
  17. HashSet<GameObject> rootsToErase = new HashSet<GameObject>(Octave3DWorldBuilder.ActiveInstance.GetRoots(gameObjectsToErase));
  18. List<GameObject> objectsToErase = GetGameObjectsWhichCanBeErased(rootsToErase);
  19. PrepareGameObjectCollectionForEraseOperation(objectsToErase);
  20. foreach (GameObject gameObject in objectsToErase) EraseEntireGameObjectHierarchy(gameObject);
  21. }
  22. public static void EraseEntireGameObjectHierarchy(GameObject gameObject)
  23. {
  24. if (!CanGameObjectBeErased(gameObject)) return;
  25. ObjectEraserSettings eraserSettings = ObjectEraserSettings.Get();
  26. GameObject root = Octave3DWorldBuilder.ActiveInstance.GetRoot(gameObject);
  27. if (root != null) DestroyGameObject(root, eraserSettings.AllowUndoRedo);
  28. }
  29. public static void EraseGameObject(GameObject gameObject)
  30. {
  31. if (!CanGameObjectBeErased(gameObject)) return;
  32. // This function is buggy - it no longer works with newer versions of Unity
  33. // because erasing children in an object hierarchy is no longer allowed. Moving
  34. // children from one parent to another is also now restricted.
  35. ObjectEraserSettings eraserSettings = ObjectEraserSettings.Get();
  36. bool isPivotWorkingObject = Octave3DWorldBuilder.ActiveInstance.IsPivotWorkingObject(gameObject);
  37. if (isPivotWorkingObject)
  38. {
  39. List<GameObject> immediateChildren = gameObject.GetImmediateChildren();
  40. gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo);
  41. DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo);
  42. for (int childIndex = 0; childIndex < immediateChildren.Count; ++childIndex)
  43. {
  44. if (ObjectQueries.IsGameObjectHierarchyEmpty(immediateChildren[childIndex]))
  45. DestroyGameObject(immediateChildren[childIndex], eraserSettings.AllowUndoRedo);
  46. }
  47. }
  48. else
  49. {
  50. GameObject root = Octave3DWorldBuilder.ActiveInstance.GetRoot(gameObject);
  51. if (root == gameObject)
  52. {
  53. List<GameObject> immediateChildren = gameObject.GetImmediateChildren();
  54. gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo);
  55. DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo);
  56. foreach(GameObject child in immediateChildren)
  57. {
  58. if (ObjectQueries.IsGameObjectHierarchyEmpty(child)) DestroyGameObject(child, eraserSettings.AllowUndoRedo);
  59. }
  60. }
  61. else
  62. {
  63. GameObject immediateParent = gameObject.transform.parent.gameObject;
  64. gameObject.MoveImmediateChildrenUpOneLevel(eraserSettings.AllowUndoRedo);
  65. DestroyGameObject(gameObject, eraserSettings.AllowUndoRedo);
  66. if (ObjectQueries.IsGameObjectHierarchyEmpty(root) && CanGameObjectBeErased(root))
  67. DestroyGameObject(root, eraserSettings.AllowUndoRedo);
  68. else
  69. if (immediateParent.transform.childCount == 0 &&
  70. ObjectQueries.IsGameObjectEmpty(immediateParent) &&
  71. !Octave3DWorldBuilder.ActiveInstance.IsPivotWorkingObject(immediateParent)) DestroyGameObject(immediateParent, eraserSettings.AllowUndoRedo);
  72. }
  73. }
  74. }
  75. public static bool CanGameObjectBeErased(GameObject gameObject)
  76. {
  77. if (gameObject == null) return false;
  78. return ObjectQueries.CanGameObjectBeInteractedWith(gameObject) && !ObjectEraser.Get().EraseMask.IsGameObjectMasked(gameObject);
  79. }
  80. #endregion
  81. #region Private Static Functions
  82. private static void DestroyGameObject(GameObject gameObject, bool allowUndoRedo)
  83. {
  84. if (allowUndoRedo) UndoEx.DestroyObjectImmediate(gameObject);
  85. else Octave3DWorldBuilder.DestroyImmediate(gameObject);
  86. }
  87. private static List<GameObject> GetGameObjectsWhichCanBeErased(IEnumerable<GameObject> gameObjects)
  88. {
  89. var objectsWhichCanBeErased = new List<GameObject>();
  90. foreach (GameObject gameObject in gameObjects)
  91. {
  92. if (CanGameObjectBeErased(gameObject)) objectsWhichCanBeErased.Add(gameObject);
  93. }
  94. return objectsWhichCanBeErased;
  95. }
  96. private static void PrepareGameObjectCollectionForEraseOperation(IEnumerable<GameObject> gameObjects)
  97. {
  98. ObjectSelection objectSelection = ObjectSelection.Get();
  99. // Note: Before objects are erased, we have to remove them from the object selection.
  100. // Otherwise, the selection information will be lost when performing an Undo
  101. // operation. I can't figure out why this is :).
  102. foreach (GameObject gameObject in gameObjects)
  103. {
  104. objectSelection.RemoveGameObjectFromSelection(gameObject);
  105. }
  106. }
  107. #endregion
  108. }
  109. }
  110. #endif