Hierarchy.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. namespace RootMotion {
  5. /// <summary>
  6. /// Contains tools for working on Transform hierarchies.
  7. /// </summary>
  8. public class Hierarchy {
  9. /// <summary>
  10. /// Make sure the bones are in valid %Hierarchy
  11. /// </summary>
  12. public static bool HierarchyIsValid(Transform[] bones) {
  13. for (int i = 1; i < bones.Length; i++) {
  14. // If parent bone is not an ancestor of bone, the hierarchy is invalid
  15. if (!IsAncestor(bones[i], bones[i - 1])) {
  16. return false;
  17. }
  18. }
  19. return true;
  20. }
  21. /// <summary>
  22. /// Checks if an array of objects contains any duplicates.
  23. /// </summary>
  24. public static UnityEngine.Object ContainsDuplicate(UnityEngine.Object[] objects) {
  25. for (int i = 0; i < objects.Length; i++) {
  26. for (int i2 = 0; i2 < objects.Length; i2++) {
  27. if (i != i2 && objects[i] == objects[i2]) return objects[i];
  28. }
  29. }
  30. return null;
  31. }
  32. /// <summary>
  33. /// Determines whether the second Transform is an ancestor to the first Transform.
  34. /// </summary>
  35. public static bool IsAncestor(Transform transform, Transform ancestor) {
  36. if (transform == null) return true;
  37. if (ancestor == null) return true;
  38. if (transform.parent == null) return false;
  39. if (transform.parent == ancestor) return true;
  40. return IsAncestor(transform.parent, ancestor);
  41. }
  42. /// <summary>
  43. /// Returns true if the transforms contains the child
  44. /// </summary>
  45. public static bool ContainsChild(Transform transform, Transform child) {
  46. if (transform == child) return true;
  47. Transform[] children = transform.GetComponentsInChildren<Transform>() as Transform[];
  48. foreach (Transform c in children) if (c == child) return true;
  49. return false;
  50. }
  51. /// <summary>
  52. /// Adds all Transforms until the blocker to the array
  53. /// </summary>
  54. public static void AddAncestors(Transform transform, Transform blocker, ref Transform[] array) {
  55. if (transform.parent != null && transform.parent != blocker) {
  56. if (transform.parent.position != transform.position && transform.parent.position != blocker.position) {
  57. Array.Resize(ref array, array.Length + 1);
  58. array[array.Length - 1] = transform.parent;
  59. }
  60. AddAncestors(transform.parent, blocker, ref array);
  61. }
  62. }
  63. /// <summary>
  64. /// Gets the last ancestor that has more than minChildCount number of child Transforms
  65. /// </summary>
  66. public static Transform GetAncestor(Transform transform, int minChildCount) {
  67. if (transform == null) return null;
  68. if (transform.parent != null) {
  69. if (transform.parent.childCount >= minChildCount) return transform.parent;
  70. return GetAncestor(transform.parent, minChildCount);
  71. }
  72. return null;
  73. }
  74. /// <summary>
  75. /// Gets the first common ancestor up the hierarchy
  76. /// </summary>
  77. public static Transform GetFirstCommonAncestor(Transform t1, Transform t2) {
  78. if (t1 == null) return null;
  79. if (t2 == null) return null;
  80. if (t1.parent == null) return null;
  81. if (t2.parent == null) return null;
  82. if (IsAncestor(t2, t1.parent)) return t1.parent;
  83. return GetFirstCommonAncestor(t1.parent, t2);
  84. }
  85. /// <summary>
  86. /// Gets the first common ancestor of the specified transforms.
  87. /// </summary>
  88. public static Transform GetFirstCommonAncestor(Transform[] transforms) {
  89. if (transforms == null) {
  90. Debug.LogWarning("Transforms is null.");
  91. return null;
  92. }
  93. if (transforms.Length == 0) {
  94. Debug.LogWarning("Transforms.Length is 0.");
  95. return null;
  96. }
  97. for (int i = 0; i < transforms.Length; i++) {
  98. if (transforms[i] == null) return null;
  99. if (IsCommonAncestor(transforms[i], transforms)) return transforms[i];
  100. }
  101. return GetFirstCommonAncestorRecursive(transforms[0], transforms);
  102. }
  103. /// <summary>
  104. /// Gets the first common ancestor recursively.
  105. /// </summary>
  106. public static Transform GetFirstCommonAncestorRecursive(Transform transform, Transform[] transforms) {
  107. if (transform == null) {
  108. Debug.LogWarning("Transform is null.");
  109. return null;
  110. }
  111. if (transforms == null) {
  112. Debug.LogWarning("Transforms is null.");
  113. return null;
  114. }
  115. if (transforms.Length == 0) {
  116. Debug.LogWarning("Transforms.Length is 0.");
  117. return null;
  118. }
  119. if (IsCommonAncestor(transform, transforms)) return transform;
  120. if (transform.parent == null) return null;
  121. return GetFirstCommonAncestorRecursive(transform.parent, transforms);
  122. }
  123. /// <summary>
  124. /// Determines whether the first parameter is the common ancestor of all the other specified transforms.
  125. /// </summary>
  126. public static bool IsCommonAncestor(Transform transform, Transform[] transforms) {
  127. if (transform == null) {
  128. Debug.LogWarning("Transform is null.");
  129. return false;
  130. }
  131. for (int i = 0; i < transforms.Length; i++) {
  132. if (transforms[i] == null) {
  133. Debug.Log("Transforms[" + i + "] is null.");
  134. return false;
  135. }
  136. if (!IsAncestor(transforms[i], transform) && transforms[i] != transform) return false;
  137. }
  138. return true;
  139. }
  140. }
  141. }