GameObjectUtils.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public class GameObjectUtils {
  4. public static List<GameObject> getAllChildren(GameObject gameObject) {
  5. var children = new List<GameObject>();
  6. foreach (Transform child in gameObject.transform) {
  7. children.Add(child.gameObject);
  8. }
  9. return children;
  10. }
  11. public static void removeAllChildren(GameObject gameObject) {
  12. var children = getAllChildren(gameObject);
  13. foreach(GameObject child in children) {
  14. destroySafely(child.gameObject);
  15. }
  16. }
  17. // TODO: allow to set bounds, align inside, outside, ...?
  18. public static void resizeToFit(GameObject gameObject, float maxWidth = 0, float maxHeight = 0, float maxDepth = 0) {
  19. // Resize an object to the desired size
  20. // Reset size for better calculation (in case any scale is set to 0)
  21. gameObject.transform.localScale = Vector3.one;
  22. // Find bounding box
  23. var bounds = getBounds(gameObject);
  24. // Scale accordingly
  25. var width = bounds.max.x - bounds.min.x;
  26. var height = bounds.max.y - bounds.min.y;
  27. var depth = bounds.max.z - bounds.min.z;
  28. var newScale = 0.0f;
  29. var tempScale = 0.0f;
  30. var scaleWillChange = false;
  31. if (maxHeight != 0) {
  32. // Decide by height
  33. tempScale = maxHeight / height;
  34. newScale = scaleWillChange ? Mathf.Min(tempScale, newScale) : tempScale;
  35. scaleWillChange = true;
  36. }
  37. if (maxDepth != 0) {
  38. // Decide by depth
  39. tempScale = maxDepth / depth;
  40. newScale = scaleWillChange ? Mathf.Min(tempScale, newScale) : tempScale;
  41. scaleWillChange = true;
  42. }
  43. if (maxWidth != 0) {
  44. // Decide by width
  45. tempScale = maxWidth / width;
  46. newScale = scaleWillChange ? Mathf.Min(tempScale, newScale) : tempScale;
  47. scaleWillChange = true;
  48. }
  49. if (scaleWillChange) {
  50. // Finally, scale
  51. gameObject.transform.localScale = new Vector3(newScale, newScale, newScale);
  52. }
  53. }
  54. public static void alignToVector(GameObject gameObject, Vector3 targetPosition, float alignX, float alignY, float alignZ) {
  55. // Align is from 0 to 1 (min to max)
  56. // TODO: move this somewhere else
  57. // TODO: allow to set bounds, align inside, outside, ...?
  58. // Also, position the object so we only use the bottom
  59. /*
  60. var newX = gameObject.transform.localPosition.x;
  61. var newZ = gameObject.transform.localPosition.z;
  62. newX = 0; // left + (gameObject.transform.position.x - bounds.min.x) * oldScaleX;
  63. var newY = (gameObject.transform.localPosition.y - bounds.min.y) * newScale;
  64. newZ = 0;
  65. gameObject.transform.localPosition = new Vector3(newX, newY, newZ);
  66. */
  67. // Find position and bounding box
  68. var bounds = getBounds(gameObject);
  69. var pivot = gameObject.transform.position;
  70. // Calculate and set new positions
  71. var newX = pivot.x - MathUtils.map(alignX, 0.0f, 1.0f, bounds.min.x, bounds.max.x);
  72. var newY = pivot.y - MathUtils.map(alignY, 0.0f, 1.0f, bounds.min.y, bounds.max.y);
  73. var newZ = pivot.z - MathUtils.map(alignZ, 0.0f, 1.0f, bounds.min.z, bounds.max.z);
  74. gameObject.transform.position = targetPosition + new Vector3(newX, newY, newZ);
  75. }
  76. public static Bounds getBounds(GameObject gameObject) {
  77. // Gets the best bounding box from a game object, using world space coordinates
  78. var bounds = new Bounds(gameObject.transform.position, new Vector3(0, 0, 0));
  79. var hasBounds = true;
  80. if (gameObject.GetComponent<Collider>() != null) {
  81. // Use collider
  82. bounds = gameObject.GetComponent<Collider>().bounds;
  83. } else if (gameObject.GetComponent<Renderer>() != null) {
  84. // Use renderer
  85. bounds = gameObject.GetComponent<Renderer>().bounds;
  86. } else {
  87. hasBounds = false;
  88. }
  89. // Find children if needed
  90. foreach (Transform child in gameObject.transform) {
  91. var childBounds = getBounds(child.gameObject);
  92. if (childBounds.extents.magnitude > 0) {
  93. if (!hasBounds) {
  94. bounds = childBounds;
  95. hasBounds = true;
  96. } else {
  97. bounds.Encapsulate(childBounds);
  98. }
  99. }
  100. }
  101. return bounds;
  102. }
  103. public static void createMeshColliders(GameObject gameObject, bool actOnChildren) {
  104. // Create mesh colliders on a specific gameObject
  105. // First, remove existing colliders
  106. removeComponents<Collider>(gameObject);
  107. // Now, create mesh colliders if meshes exist
  108. var mesh = gameObject.GetComponent<MeshFilter>();
  109. if (mesh != null) {
  110. var meshCollider = gameObject.AddComponent<MeshCollider>();
  111. meshCollider.convex = false;
  112. meshCollider.isTrigger = false;
  113. }
  114. // Recurse into children if desired
  115. if (actOnChildren) {
  116. foreach (Transform child in gameObject.transform) {
  117. createMeshColliders(child.gameObject, true);
  118. }
  119. }
  120. }
  121. public static void setRenderersVisibility(GameObject gameObject, bool visible) {
  122. var renderers = gameObject.GetComponentsInChildren<Renderer>();
  123. foreach (var renderer in renderers) {
  124. renderer.enabled = visible;
  125. }
  126. }
  127. public static void setCollidersEnabled(GameObject gameObject, bool visible) {
  128. var colliders = gameObject.GetComponentsInChildren<Collider>();
  129. foreach (var collider in colliders) {
  130. collider.enabled = visible;
  131. }
  132. }
  133. public static void setAlpha(GameObject gameObject, float alpha) {
  134. var renderers = gameObject.GetComponentsInChildren<Renderer>();
  135. foreach (var renderer in renderers) {
  136. foreach (var material in renderer.sharedMaterials) {
  137. material.color = new Color(material.color.r, material.color.g, material.color.b, alpha);
  138. }
  139. }
  140. }
  141. public static void removeComponents<T>(GameObject gameObject) where T:Component {
  142. var components = gameObject.GetComponents<T>();
  143. foreach (Component component in components) {
  144. destroySafely(component);
  145. }
  146. }
  147. public static void destroySafely(GameObject gameObject) {
  148. #if UNITY_EDITOR
  149. GameObject.DestroyImmediate(gameObject);
  150. #else
  151. GameObject.Destroy(gameObject);
  152. #endif
  153. }
  154. public static void destroySafely(Component component) {
  155. #if UNITY_EDITOR
  156. GameObject.DestroyImmediate(component);
  157. #else
  158. GameObject.Destroy(component);
  159. #endif
  160. }
  161. }