HierarchyHandler.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Shatter Toolkit
  2. // Copyright 2015 Gustav Olsson
  3. using UnityEngine;
  4. namespace ShatterToolkit.Helpers
  5. {
  6. [RequireComponent(typeof(ShatterTool))]
  7. public class HierarchyHandler : MonoBehaviour
  8. {
  9. public bool attachPieceToParent = true;
  10. public float maxPieceToParentDistance = 1.0f;
  11. public bool addRbToDetachedPieces = true;
  12. public bool attachChildrenToPieces = true;
  13. public float maxChildToPieceDistance = 1.0f;
  14. public bool addRbToDetachedChildren = true;
  15. protected Transform parent;
  16. protected Transform[] children;
  17. public void PreSplit(Plane[] planes)
  18. {
  19. // Save and detach parent
  20. if (transform.parent != null)
  21. {
  22. parent = transform.parent;
  23. transform.parent = null;
  24. }
  25. // Save and detach children
  26. children = new Transform[transform.childCount];
  27. int index = 0;
  28. foreach (Transform child in transform)
  29. {
  30. children[index++] = child;
  31. }
  32. transform.DetachChildren();
  33. }
  34. public void PostSplit(GameObject[] newGameObjects)
  35. {
  36. // Get shatter tool scripts of the new game objects
  37. ShatterTool[] pieces = new ShatterTool[newGameObjects.Length];
  38. for (int i = 0; i < newGameObjects.Length; i++)
  39. {
  40. pieces[i] = newGameObjects[i].GetComponent<ShatterTool>();
  41. }
  42. // Attach one of the new pieces to the original parent
  43. if (parent != null)
  44. {
  45. ShatterTool parentShatterTool = parent.GetComponent<ShatterTool>();
  46. if (parentShatterTool != null)
  47. {
  48. // Which piece should attach to the original parent?
  49. ShatterTool closestPiece = null;
  50. if (attachPieceToParent)
  51. {
  52. closestPiece = FindClosestPiece(parentShatterTool, pieces, maxPieceToParentDistance);
  53. if (closestPiece != null)
  54. {
  55. closestPiece.transform.parent = parent;
  56. }
  57. }
  58. // Add rigidbodies to the detached pieces
  59. if (addRbToDetachedPieces)
  60. {
  61. foreach (ShatterTool piece in pieces)
  62. {
  63. if (piece != null && piece != closestPiece)
  64. {
  65. piece.gameObject.AddComponent<Rigidbody>();
  66. }
  67. }
  68. }
  69. }
  70. }
  71. // Attach the original children to the new pieces
  72. foreach (Transform child in children)
  73. {
  74. ShatterTool childShatterTool = child.GetComponent<ShatterTool>();
  75. if (childShatterTool != null)
  76. {
  77. // Which piece should this child attach to?
  78. ShatterTool closestPiece = FindClosestPiece(childShatterTool, pieces, maxChildToPieceDistance);
  79. if (attachChildrenToPieces && closestPiece != null)
  80. {
  81. child.parent = closestPiece.transform;
  82. }
  83. else
  84. {
  85. if (addRbToDetachedChildren)
  86. {
  87. child.gameObject.AddComponent<Rigidbody>();
  88. }
  89. }
  90. }
  91. }
  92. }
  93. protected ShatterTool FindClosestPiece(ShatterTool reference, ShatterTool[] pieces, float maxDistance)
  94. {
  95. Vector3 center = reference.Center;
  96. float maxDistanceSqr = maxDistance * maxDistance;
  97. ShatterTool closestPiece = null;
  98. float closestDistanceSqr = 0.0f;
  99. for (int i = 0; i < pieces.Length; i++)
  100. {
  101. ShatterTool piece = pieces[i];
  102. if (piece != null)
  103. {
  104. float distanceSqr = (center - piece.Center).sqrMagnitude;
  105. if (distanceSqr < maxDistanceSqr && (distanceSqr < closestDistanceSqr || closestPiece == null))
  106. {
  107. closestPiece = piece;
  108. closestDistanceSqr = distanceSqr;
  109. }
  110. }
  111. }
  112. return closestPiece;
  113. }
  114. }
  115. }