| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // Shatter Toolkit
- // Copyright 2015 Gustav Olsson
- using UnityEngine;
- namespace ShatterToolkit.Helpers
- {
- [RequireComponent(typeof(ShatterTool))]
- public class HierarchyHandler : MonoBehaviour
- {
- public bool attachPieceToParent = true;
- public float maxPieceToParentDistance = 1.0f;
- public bool addRbToDetachedPieces = true;
-
- public bool attachChildrenToPieces = true;
- public float maxChildToPieceDistance = 1.0f;
- public bool addRbToDetachedChildren = true;
-
- protected Transform parent;
- protected Transform[] children;
-
- public void PreSplit(Plane[] planes)
- {
- // Save and detach parent
- if (transform.parent != null)
- {
- parent = transform.parent;
-
- transform.parent = null;
- }
-
- // Save and detach children
- children = new Transform[transform.childCount];
-
- int index = 0;
-
- foreach (Transform child in transform)
- {
- children[index++] = child;
- }
-
- transform.DetachChildren();
- }
-
- public void PostSplit(GameObject[] newGameObjects)
- {
- // Get shatter tool scripts of the new game objects
- ShatterTool[] pieces = new ShatterTool[newGameObjects.Length];
-
- for (int i = 0; i < newGameObjects.Length; i++)
- {
- pieces[i] = newGameObjects[i].GetComponent<ShatterTool>();
- }
-
- // Attach one of the new pieces to the original parent
- if (parent != null)
- {
- ShatterTool parentShatterTool = parent.GetComponent<ShatterTool>();
-
- if (parentShatterTool != null)
- {
- // Which piece should attach to the original parent?
- ShatterTool closestPiece = null;
-
- if (attachPieceToParent)
- {
- closestPiece = FindClosestPiece(parentShatterTool, pieces, maxPieceToParentDistance);
-
- if (closestPiece != null)
- {
- closestPiece.transform.parent = parent;
- }
- }
-
- // Add rigidbodies to the detached pieces
- if (addRbToDetachedPieces)
- {
- foreach (ShatterTool piece in pieces)
- {
- if (piece != null && piece != closestPiece)
- {
- piece.gameObject.AddComponent<Rigidbody>();
- }
- }
- }
- }
- }
-
- // Attach the original children to the new pieces
- foreach (Transform child in children)
- {
- ShatterTool childShatterTool = child.GetComponent<ShatterTool>();
-
- if (childShatterTool != null)
- {
- // Which piece should this child attach to?
- ShatterTool closestPiece = FindClosestPiece(childShatterTool, pieces, maxChildToPieceDistance);
-
- if (attachChildrenToPieces && closestPiece != null)
- {
- child.parent = closestPiece.transform;
- }
- else
- {
- if (addRbToDetachedChildren)
- {
- child.gameObject.AddComponent<Rigidbody>();
- }
- }
- }
- }
- }
-
- protected ShatterTool FindClosestPiece(ShatterTool reference, ShatterTool[] pieces, float maxDistance)
- {
- Vector3 center = reference.Center;
- float maxDistanceSqr = maxDistance * maxDistance;
-
- ShatterTool closestPiece = null;
- float closestDistanceSqr = 0.0f;
-
- for (int i = 0; i < pieces.Length; i++)
- {
- ShatterTool piece = pieces[i];
-
- if (piece != null)
- {
- float distanceSqr = (center - piece.Center).sqrMagnitude;
-
- if (distanceSqr < maxDistanceSqr && (distanceSqr < closestDistanceSqr || closestPiece == null))
- {
- closestPiece = piece;
- closestDistanceSqr = distanceSqr;
- }
- }
- }
-
- return closestPiece;
- }
- }
- }
|