diff --git a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs b/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs index 2d53eb670..fddac4897 100644 --- a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs +++ b/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs @@ -28,17 +28,16 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ - using UnityEngine; -using System.Collections; -using Spine; -public delegate void UpdateBonesDelegate (ISkeletonAnimation skeletonRenderer); -public interface ISkeletonAnimation { - event UpdateBonesDelegate UpdateLocal; - event UpdateBonesDelegate UpdateWorld; - event UpdateBonesDelegate UpdateComplete; +namespace Spine.Unity { + public delegate void UpdateBonesDelegate (ISkeletonAnimation skeletonRenderer); + public interface ISkeletonAnimation { + event UpdateBonesDelegate UpdateLocal; + event UpdateBonesDelegate UpdateWorld; + event UpdateBonesDelegate UpdateComplete; - void LateUpdate (); - Skeleton Skeleton { get; } + void LateUpdate (); + Skeleton Skeleton { get; } + } } diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs index f1398b58e..72d30a18e 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs +++ b/spine-unity/Assets/spine-unity/Modules/SkeletonUtility Modules/SkeletonUtilityKinematicShadow.cs @@ -33,82 +33,93 @@ using UnityEngine; using System.Collections.Generic; namespace Spine.Unity.Modules { + + // SkeletonUtilityKinematicShadow allows hinge chains to inherit a velocity interpreted from changes in parent transform position or from unrelated rigidbodies. + // Note: Uncheck "useRootTransformIfNull public class SkeletonUtilityKinematicShadow : MonoBehaviour { - public bool hideShadow = true; + #region Inspector + [Tooltip("If checked, the hinge chain can inherit your root transform's velocity or position/rotation changes.")] + public bool detachedShadow = false; public Transform parent; - Dictionary shadowTable; + public bool hideShadow = true; + #endregion + GameObject shadowRoot; + readonly List shadowTable = new List(); + struct TransformPair { + public Transform dest, src; + } void Start () { - shadowRoot = (GameObject)Instantiate(gameObject); - if (hideShadow) - shadowRoot.hideFlags = HideFlags.HideInHierarchy; - - if (parent == null) - shadowRoot.transform.parent = transform.root; - else - shadowRoot.transform.parent = parent; - - shadowTable = new Dictionary(); - + // Duplicate this gameObject as the "shadow" with a different parent. + shadowRoot = Instantiate(this.gameObject); Destroy(shadowRoot.GetComponent()); - shadowRoot.transform.position = transform.position; - shadowRoot.transform.rotation = transform.rotation; + // Prepare shadow gameObject's properties. + var shadowRootTransform = shadowRoot.transform; + shadowRootTransform.position = transform.position; + shadowRootTransform.rotation = transform.rotation; Vector3 scaleRef = transform.TransformPoint(Vector3.right); float scale = Vector3.Distance(transform.position, scaleRef); - shadowRoot.transform.localScale = Vector3.one; + shadowRootTransform.localScale = Vector3.one; - var shadowJoints = shadowRoot.GetComponentsInChildren(); - foreach (Joint j in shadowJoints) { - j.connectedAnchor *= scale; + if (!detachedShadow) { + // Do not change to null coalescing operator (??). Unity overloads null checks for UnityEngine.Objects but not the ?? operator. + if (parent == null) + shadowRootTransform.parent = transform.root; + else + shadowRootTransform.parent = parent; } - var joints = GetComponentsInChildren(); - foreach (var j in joints) - Destroy(j); + if (hideShadow) + shadowRoot.hideFlags = HideFlags.HideInHierarchy; + + var shadowJoints = shadowRoot.GetComponentsInChildren(); + foreach (Joint j in shadowJoints) + j.connectedAnchor *= scale; - var rbs = GetComponentsInChildren(); - foreach (var rb in rbs) - Destroy(rb); - - var colliders = GetComponentsInChildren(); - foreach (var c in colliders) - Destroy(c); - - - //match by bone name - var shadowBones = shadowRoot.GetComponentsInChildren(); + // Build list of bone pairs (matches shadow transforms with bone transforms) var bones = GetComponentsInChildren(); - - //build bone lookup + var shadowBones = shadowRoot.GetComponentsInChildren(); foreach (var b in bones) { - if (b.gameObject == gameObject) + if (b.gameObject == this.gameObject) continue; - + foreach (var sb in shadowBones) { - if (sb.GetComponent() == null) - continue; - - if (sb.boneName == b.boneName) { - shadowTable.Add(sb.transform, b.transform); + if (sb.GetComponent() != null && sb.boneName == b.boneName) { + shadowTable.Add(new TransformPair { + dest = b.transform, + src = sb.transform + }); break; } } + } - foreach (var b in shadowBones) - Destroy(b); + // Destroy conflicting and unneeded components + DestroyComponents(shadowBones); + + DestroyComponents(GetComponentsInChildren()); + DestroyComponents(GetComponentsInChildren()); + DestroyComponents(GetComponentsInChildren()); + } + + static void DestroyComponents (Component[] components) { + for (int i = 0, n = components.Length; i < n; i++) + Destroy(components[i]); } void FixedUpdate () { - shadowRoot.GetComponent().MovePosition(transform.position); - shadowRoot.GetComponent().MoveRotation(transform.rotation); + var shadowRootRigidbody = shadowRoot.GetComponent(); + shadowRootRigidbody.MovePosition(transform.position); + shadowRootRigidbody.MoveRotation(transform.rotation); - foreach (var pair in shadowTable) { - pair.Value.localPosition = pair.Key.localPosition; - pair.Value.localRotation = pair.Key.localRotation; + for (int i = 0, n = shadowTable.Count; i < n; i++) { + var pair = shadowTable[i]; + pair.dest.localPosition = pair.src.localPosition; + pair.dest.localRotation = pair.src.localRotation; } } }