Merge remote-tracking branch 'origin/master'

This commit is contained in:
NathanSweet 2016-05-06 23:09:54 +02:00
commit d7fb4f35ec
2 changed files with 69 additions and 59 deletions

View File

@ -28,17 +28,16 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
using UnityEngine; using UnityEngine;
using System.Collections;
using Spine;
public delegate void UpdateBonesDelegate (ISkeletonAnimation skeletonRenderer); namespace Spine.Unity {
public interface ISkeletonAnimation { public delegate void UpdateBonesDelegate (ISkeletonAnimation skeletonRenderer);
event UpdateBonesDelegate UpdateLocal; public interface ISkeletonAnimation {
event UpdateBonesDelegate UpdateWorld; event UpdateBonesDelegate UpdateLocal;
event UpdateBonesDelegate UpdateComplete; event UpdateBonesDelegate UpdateWorld;
event UpdateBonesDelegate UpdateComplete;
void LateUpdate (); void LateUpdate ();
Skeleton Skeleton { get; } Skeleton Skeleton { get; }
}
} }

View File

@ -33,82 +33,93 @@ using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
namespace Spine.Unity.Modules { 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 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; public Transform parent;
Dictionary<Transform, Transform> shadowTable; public bool hideShadow = true;
#endregion
GameObject shadowRoot; GameObject shadowRoot;
readonly List<TransformPair> shadowTable = new List<TransformPair>();
struct TransformPair {
public Transform dest, src;
}
void Start () { void Start () {
shadowRoot = (GameObject)Instantiate(gameObject); // Duplicate this gameObject as the "shadow" with a different parent.
if (hideShadow) shadowRoot = Instantiate<GameObject>(this.gameObject);
shadowRoot.hideFlags = HideFlags.HideInHierarchy;
if (parent == null)
shadowRoot.transform.parent = transform.root;
else
shadowRoot.transform.parent = parent;
shadowTable = new Dictionary<Transform, Transform>();
Destroy(shadowRoot.GetComponent<SkeletonUtilityKinematicShadow>()); Destroy(shadowRoot.GetComponent<SkeletonUtilityKinematicShadow>());
shadowRoot.transform.position = transform.position; // Prepare shadow gameObject's properties.
shadowRoot.transform.rotation = transform.rotation; var shadowRootTransform = shadowRoot.transform;
shadowRootTransform.position = transform.position;
shadowRootTransform.rotation = transform.rotation;
Vector3 scaleRef = transform.TransformPoint(Vector3.right); Vector3 scaleRef = transform.TransformPoint(Vector3.right);
float scale = Vector3.Distance(transform.position, scaleRef); float scale = Vector3.Distance(transform.position, scaleRef);
shadowRoot.transform.localScale = Vector3.one; shadowRootTransform.localScale = Vector3.one;
var shadowJoints = shadowRoot.GetComponentsInChildren<Joint>(); if (!detachedShadow) {
foreach (Joint j in shadowJoints) { // Do not change to null coalescing operator (??). Unity overloads null checks for UnityEngine.Objects but not the ?? operator.
j.connectedAnchor *= scale; if (parent == null)
shadowRootTransform.parent = transform.root;
else
shadowRootTransform.parent = parent;
} }
var joints = GetComponentsInChildren<Joint>(); if (hideShadow)
foreach (var j in joints) shadowRoot.hideFlags = HideFlags.HideInHierarchy;
Destroy(j);
var rbs = GetComponentsInChildren<Rigidbody>(); var shadowJoints = shadowRoot.GetComponentsInChildren<Joint>();
foreach (var rb in rbs) foreach (Joint j in shadowJoints)
Destroy(rb); j.connectedAnchor *= scale;
var colliders = GetComponentsInChildren<Collider>(); // Build list of bone pairs (matches shadow transforms with bone transforms)
foreach (var c in colliders)
Destroy(c);
//match by bone name
var shadowBones = shadowRoot.GetComponentsInChildren<SkeletonUtilityBone>();
var bones = GetComponentsInChildren<SkeletonUtilityBone>(); var bones = GetComponentsInChildren<SkeletonUtilityBone>();
var shadowBones = shadowRoot.GetComponentsInChildren<SkeletonUtilityBone>();
//build bone lookup
foreach (var b in bones) { foreach (var b in bones) {
if (b.gameObject == gameObject) if (b.gameObject == this.gameObject)
continue; continue;
foreach (var sb in shadowBones) { foreach (var sb in shadowBones) {
if (sb.GetComponent<Rigidbody>() == null) if (sb.GetComponent<Rigidbody>() != null && sb.boneName == b.boneName) {
continue; shadowTable.Add(new TransformPair {
dest = b.transform,
if (sb.boneName == b.boneName) { src = sb.transform
shadowTable.Add(sb.transform, b.transform); });
break; break;
} }
} }
} }
foreach (var b in shadowBones) // Destroy conflicting and unneeded components
Destroy(b); DestroyComponents(shadowBones);
DestroyComponents(GetComponentsInChildren<Joint>());
DestroyComponents(GetComponentsInChildren<Rigidbody>());
DestroyComponents(GetComponentsInChildren<Collider>());
}
static void DestroyComponents (Component[] components) {
for (int i = 0, n = components.Length; i < n; i++)
Destroy(components[i]);
} }
void FixedUpdate () { void FixedUpdate () {
shadowRoot.GetComponent<Rigidbody>().MovePosition(transform.position); var shadowRootRigidbody = shadowRoot.GetComponent<Rigidbody>();
shadowRoot.GetComponent<Rigidbody>().MoveRotation(transform.rotation); shadowRootRigidbody.MovePosition(transform.position);
shadowRootRigidbody.MoveRotation(transform.rotation);
foreach (var pair in shadowTable) { for (int i = 0, n = shadowTable.Count; i < n; i++) {
pair.Value.localPosition = pair.Key.localPosition; var pair = shadowTable[i];
pair.Value.localRotation = pair.Key.localRotation; pair.dest.localPosition = pair.src.localPosition;
pair.dest.localRotation = pair.src.localRotation;
} }
} }
} }