Browse Source

Merge branch '3.6' into 3.7-beta

badlogic 8 years ago
parent
commit
6137da3eb2
18 changed files with 551 additions and 485 deletions
  1. 18 5
      spine-c/spine-c/src/spine/Animation.c
  2. 2 1
      spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
  3. 45 28
      spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs
  4. 410 410
      spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs
  5. 1 1
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc
  6. 1 1
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc
  7. 3 3
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader
  8. 3 3
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader
  9. 3 3
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader
  10. 0 2
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc
  11. 0 2
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader
  12. 2 2
      spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc
  13. 28 10
      spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader
  14. 29 6
      spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader
  15. 0 2
      spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader
  16. 1 1
      spine-unity/Assets/spine-unity/SkeletonAnimation.cs
  17. 1 1
      spine-unity/Assets/spine-unity/SkeletonRenderer.cs
  18. 4 4
      spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs

+ 18 - 5
spine-c/spine-c/src/spine/Animation.c

@@ -851,22 +851,35 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
 			slot->attachmentVerticesCapacity = vertexCount;
 		}
 	}
-	if (slot->attachmentVerticesCount != vertexCount && pose != SP_MIX_POSE_SETUP) alpha = 1; /* Don't mix from uninitialized slot vertices. */
 	slot->attachmentVerticesCount = vertexCount;
 
 	frameVertices = self->frameVertices;
 	vertices = slot->attachmentVertices;
 
 	if (time < frames[0]) { /* Time is before first frame. */
+		spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
 		switch (pose) {
 			case SP_MIX_POSE_SETUP:
-				slot->attachmentVerticesCount = 0;
+				if (!vertexAttachment->bones) {
+					memcpy(vertices, vertexAttachment->vertices, vertexCount * sizeof(float));
+				} else {
+					for (i = 0; i < vertexCount; i++) vertices[i] = 0;
+				}
 				return;
 			case SP_MIX_POSE_CURRENT:
 			case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
-				alpha = 1 - alpha;
-				for (i = 0; i < vertexCount; i++)
-					vertices[i] *= alpha;
+				if (alpha == 1) break;
+				if (!vertexAttachment->bones) {
+					float* setupVertices = vertexAttachment->vertices;
+					for (i = 0; i < vertexCount; i++) {
+						vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
+					}
+				} else {
+					alpha = 1 - alpha;
+					for (i = 0; i < vertexCount; i++) {
+						vertices[i] *= alpha;
+					}
+				}
 		}
 		return;
 	}

+ 2 - 1
spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs

@@ -99,8 +99,9 @@ namespace Spine.Unity.Editor {
 				skeletonDataAsset = property.serializedObject.targetObject as SkeletonDataAsset;
 				if (skeletonDataAsset == null) return;
 			}
-
+				
 			position = EditorGUI.PrefixLabel(position, label);
+
 			var image = Icon;
 			var propertyStringValue = (property.hasMultipleDifferentValues) ? SpineInspectorUtility.EmDash : property.stringValue;
 			if (GUI.Button(position, string.IsNullOrEmpty(propertyStringValue) ? NoneLabel(image) : SpineInspectorUtility.TempContent(propertyStringValue, image), EditorStyles.popup))

+ 45 - 28
spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs

@@ -79,7 +79,7 @@ namespace Spine.Unity {
 
 		/// <summary>
 		/// Initialize and instantiate the BoundingBoxFollower colliders. This is method checks if the BoundingBoxFollower has already been initialized for the skeleton instance and slotName and prevents overwriting unless it detects a new setup.</summary>
-		public void Initialize () {
+		public void Initialize (bool overwrite = false) {
 			if (skeletonRenderer == null)
 				return;
 
@@ -89,7 +89,9 @@ namespace Spine.Unity {
 				return;
 
 			// Don't reinitialize if the setup did not change.
-			if (colliderTable.Count > 0 && slot != null			// Slot is set and colliders already populated.
+			if (!overwrite
+				&&
+				colliderTable.Count > 0 && slot != null			// Slot is set and colliders already populated.
 				&&
 				skeletonRenderer.skeleton == slot.Skeleton		// Skeleton object did not change.
 				&&
@@ -110,27 +112,10 @@ namespace Spine.Unity {
 			}
 
 			if (this.gameObject.activeInHierarchy) {
-				foreach (var skin in skeleton.Data.Skins) {
-					var attachmentNames = new List<string>();
-					skin.FindNamesForSlot(slotIndex, attachmentNames);
-
-					foreach (var skinKey in attachmentNames) {
-						var attachment = skin.GetAttachment(slotIndex, skinKey);
-						var boundingBoxAttachment = attachment as BoundingBoxAttachment;
-
-						if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null)
-							Debug.Log("BoundingBoxFollower tried to follow a slot that contains non-boundingbox attachments: " + slotName);						
-
-						if (boundingBoxAttachment != null) {
-							var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger);
-							bbCollider.enabled = false;
-							bbCollider.hideFlags = HideFlags.NotEditable;
-							bbCollider.isTrigger = IsTrigger;
-							colliderTable.Add(boundingBoxAttachment, bbCollider);
-							nameTable.Add(boundingBoxAttachment, skinKey);
-						}
-					}
-				}
+				foreach (var skin in skeleton.Data.Skins)
+					AddSkin(skin, skeleton, slotIndex);
+
+				AddSkin(skeleton.skin, skeleton, slotIndex);
 			}
 
 			if (BoundingBoxFollower.DebugMessages) {
@@ -144,6 +129,28 @@ namespace Spine.Unity {
 			}
 		}
 
+		void AddSkin (Skin skin, Skeleton skeleton, int slotIndex) {
+			var attachmentNames = new List<string>();
+			skin.FindNamesForSlot(slotIndex, attachmentNames);
+
+			foreach (var skinKey in attachmentNames) {
+				var attachment = skin.GetAttachment(slotIndex, skinKey);
+				var boundingBoxAttachment = attachment as BoundingBoxAttachment;
+
+				if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null)
+					Debug.Log("BoundingBoxFollower tried to follow a slot that contains non-boundingbox attachments: " + slotName);
+
+				if (boundingBoxAttachment != null) {
+					var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger);
+					bbCollider.enabled = false;
+					bbCollider.hideFlags = HideFlags.NotEditable;
+					bbCollider.isTrigger = IsTrigger;
+					colliderTable.Add(boundingBoxAttachment, bbCollider);
+					nameTable.Add(boundingBoxAttachment, skinKey);
+				}
+			}
+		}
+
 		void OnDisable () {
 			if (clearStateOnDisable)
 				ClearState();
@@ -206,13 +213,23 @@ namespace Spine.Unity {
 
 			if (bbAttachment == null) {
 				currentCollider = null;
+				currentAttachment = null;
+				currentAttachmentName = null;
 			} else {
-				currentCollider = colliderTable[bbAttachment];
-				currentCollider.enabled = true;
+				PolygonCollider2D foundCollider;
+				colliderTable.TryGetValue(bbAttachment, out foundCollider);
+				if (foundCollider != null) {
+					currentCollider = foundCollider;
+					currentCollider.enabled = true;
+					currentAttachment = bbAttachment;
+					currentAttachmentName = nameTable[bbAttachment];
+				} else {
+					currentCollider = null;
+					currentAttachment = bbAttachment;
+					currentAttachmentName = null;
+					if (BoundingBoxFollower.DebugMessages) Debug.LogFormat("Collider for BoundingBoxAttachment named '{0}' was not initialized. It is possibly from a new skin. currentAttachmentName will be null. You may need to call BoundingBoxFollower.Initialize(overwrite: true);", bbAttachment.Name);
+				}
 			}
-
-			currentAttachment = bbAttachment;
-			currentAttachmentName = currentAttachment == null ? null : nameTable[bbAttachment];
 		}
 	}
 

+ 410 - 410
spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs

@@ -1,410 +1,410 @@
-/******************************************************************************
- * Spine Runtimes Software License v2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-// Contributed by: Mitch Thompson
-
-using UnityEngine;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace Spine.Unity.Modules {
-	[RequireComponent(typeof(SkeletonRenderer))]
-	public class SkeletonRagdoll2D : MonoBehaviour {
-		static Transform parentSpaceHelper;
-
-		#region Inspector
-		[Header("Hierarchy")]
-		[SpineBone]
-		public string startingBoneName = "";
-		[SpineBone]
-		public List<string> stopBoneNames = new List<string>();
-
-		[Header("Parameters")]
-		public bool applyOnStart;
-		[Tooltip("Warning!  You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")]
-		public bool disableIK = true;
-		public bool disableOtherConstraints = false;
-		[Space]
-		[Tooltip("Set RootRigidbody IsKinematic to true when Apply is called.")]
-		public bool pinStartBone;
-		public float gravityScale = 1;
-		[Tooltip("If no BoundingBox Attachment is attached to a bone, this becomes the default Width or Radius of a Bone's ragdoll Rigidbody")]
-		public float thickness = 0.125f;
-		[Tooltip("Default rotational limit value.  Min is negative this value, Max is this value.")]
-		public float rotationLimit = 20;
-		public float rootMass = 20;
-		[Tooltip("If your ragdoll seems unstable or uneffected by limits, try lowering this value.")]
-		[Range(0.01f, 1f)]
-		public float massFalloffFactor = 0.4f;
-		[Tooltip("The layer assigned to all of the rigidbody parts.")]
-		[SkeletonRagdoll.LayerField]
-		public int colliderLayer = 0;
-		[Range(0, 1)]
-		public float mix = 1;
-		#endregion
-
-		ISkeletonAnimation targetSkeletonComponent;
-		Skeleton skeleton;
-		Dictionary<Bone, Transform> boneTable = new Dictionary<Bone, Transform>();
-		Transform ragdollRoot;
-		public Rigidbody2D RootRigidbody { get; private set; }
-		public Bone StartingBone { get; private set; }
-		Vector2 rootOffset;
-		public Vector3 RootOffset { get { return this.rootOffset; } }
-		bool isActive;
-		public bool IsActive { get { return this.isActive; } }
-
-		IEnumerator Start () {
-			if (parentSpaceHelper == null) {
-				parentSpaceHelper = (new GameObject("Parent Space Helper")).transform;
-			}
-
-			targetSkeletonComponent = GetComponent<SkeletonRenderer>() as ISkeletonAnimation;
-			if (targetSkeletonComponent == null) Debug.LogError("Attached Spine component does not implement ISkeletonAnimation. This script is not compatible.");
-			skeleton = targetSkeletonComponent.Skeleton;
-
-			if (applyOnStart) {
-				yield return null;
-				Apply();
-			}
-		}
-
-		#region API
-		public Rigidbody2D[] RigidbodyArray {
-			get {
-				if (!isActive)
-					return new Rigidbody2D[0];
-
-				var rigidBodies = new Rigidbody2D[boneTable.Count];
-				int i = 0;
-				foreach (Transform t in boneTable.Values) {
-					rigidBodies[i] = t.GetComponent<Rigidbody2D>();
-					i++;
-				}
-
-				return rigidBodies;
-			}
-		}
-
-		public Vector3 EstimatedSkeletonPosition {
-			get { return this.RootRigidbody.position - rootOffset; }
-		}
-
-		/// <summary>Instantiates the ragdoll simulation and applies its transforms to the skeleton.</summary>
-		public void Apply () {
-			isActive = true;
-			mix = 1;
-
-			Bone startingBone = this.StartingBone = skeleton.FindBone(startingBoneName);
-			RecursivelyCreateBoneProxies(startingBone);
-
-			RootRigidbody = boneTable[startingBone].GetComponent<Rigidbody2D>();
-			RootRigidbody.isKinematic = pinStartBone;
-			RootRigidbody.mass = rootMass;
-			var boneColliders = new List<Collider2D>();
-			foreach (var pair in boneTable) {
-				var b = pair.Key;
-				var t = pair.Value;
-				Transform parentTransform;
-				boneColliders.Add(t.GetComponent<Collider2D>());
-				if (b == startingBone) {
-					ragdollRoot = new GameObject("RagdollRoot").transform;
-					ragdollRoot.SetParent(transform, false);
-					if (b == skeleton.RootBone) { // RagdollRoot is skeleton root.
-						ragdollRoot.localPosition = new Vector3(b.WorldX, b.WorldY, 0);
-						ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b));
-					} else {
-						ragdollRoot.localPosition = new Vector3(b.Parent.WorldX, b.Parent.WorldY, 0);
-						ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b.Parent));
-					}
-					parentTransform = ragdollRoot;
-					rootOffset = t.position - transform.position;
-				} else {
-					parentTransform = boneTable[b.Parent];
-				}
-
-				// Add joint and attach to parent.
-				var rbParent = parentTransform.GetComponent<Rigidbody2D>();
-				if (rbParent != null) {
-					var joint = t.gameObject.AddComponent<HingeJoint2D>();
-					joint.connectedBody = rbParent;
-					Vector3 localPos = parentTransform.InverseTransformPoint(t.position);
-					joint.connectedAnchor = localPos;
-
-					joint.GetComponent<Rigidbody2D>().mass = joint.connectedBody.mass * massFalloffFactor;
-					joint.limits = new JointAngleLimits2D {
-						min = -rotationLimit,
-						max = rotationLimit
-					};
-					joint.useLimits = true;
-				}
-			}
-
-			// Ignore collisions among bones.
-			for (int x = 0; x < boneColliders.Count; x++) {
-				for (int y = 0; y < boneColliders.Count; y++) {
-					if (x == y) continue;
-					Physics2D.IgnoreCollision(boneColliders[x], boneColliders[y]);
-				}
-			}
-
-			// Destroy existing override-mode SkeletonUtility bones.
-			var utilityBones = GetComponentsInChildren<SkeletonUtilityBone>();
-			if (utilityBones.Length > 0) {
-				var destroyedUtilityBoneNames = new List<string>();
-				foreach (var ub in utilityBones) {
-					if (ub.mode == SkeletonUtilityBone.Mode.Override) {
-						destroyedUtilityBoneNames.Add(ub.gameObject.name);
-						Destroy(ub.gameObject);
-					}
-				}
-				if (destroyedUtilityBoneNames.Count > 0) {
-					string msg = "Destroyed Utility Bones: ";
-					for (int i = 0; i < destroyedUtilityBoneNames.Count; i++) {
-						msg += destroyedUtilityBoneNames[i];
-						if (i != destroyedUtilityBoneNames.Count - 1) {
-							msg += ",";
-						}
-					}
-					Debug.LogWarning(msg);
-				}
-			}
-
-			// Disable skeleton constraints.
-			if (disableIK) {
-				var ikConstraints = skeleton.IkConstraints;
-				for (int i = 0, n = ikConstraints.Count; i < n; i++)
-					ikConstraints.Items[i].mix = 0;
-			}
-
-			if (disableOtherConstraints) {
-				var transformConstraints = skeleton.transformConstraints;
-				for (int i = 0, n = transformConstraints.Count; i < n; i++) {
-					transformConstraints.Items[i].rotateMix = 0;
-					transformConstraints.Items[i].scaleMix = 0;
-					transformConstraints.Items[i].shearMix = 0;
-					transformConstraints.Items[i].translateMix = 0;
-				}
-
-				var pathConstraints = skeleton.pathConstraints;
-				for (int i = 0, n = pathConstraints.Count; i < n; i++) {
-					pathConstraints.Items[i].rotateMix = 0;
-					pathConstraints.Items[i].translateMix = 0;
-				}
-			}
-
-			targetSkeletonComponent.UpdateWorld += UpdateSpineSkeleton;
-		}
-
-		/// <summary>Transitions the mix value from the current value to a target value.</summary>
-		public Coroutine SmoothMix (float target, float duration) {
-			return StartCoroutine(SmoothMixCoroutine(target, duration));
-		}
-
-		IEnumerator SmoothMixCoroutine (float target, float duration) {
-			float startTime = Time.time;
-			float startMix = mix;
-			while (mix > 0) {
-				skeleton.SetBonesToSetupPose();
-				mix = Mathf.SmoothStep(startMix, target, (Time.time - startTime) / duration);
-				yield return null;
-			}
-		}
-
-		/// <summary>Set the transform world position while preserving the ragdoll parts world position.</summary>
-		public void SetSkeletonPosition (Vector3 worldPosition) {
-			if (!isActive) {
-				Debug.LogWarning("Can't call SetSkeletonPosition while Ragdoll is not active!");
-				return;
-			}
-
-			Vector3 offset = worldPosition - transform.position;
-			transform.position = worldPosition;
-			foreach (Transform t in boneTable.Values)
-				t.position -= offset;
-
-			UpdateSpineSkeleton(null);
-			skeleton.UpdateWorldTransform();
-		}
-
-		/// <summary>Removes the ragdoll instance and effect from the animated skeleton.</summary>
-		public void Remove () {
-			isActive = false;
-			foreach (var t in boneTable.Values)
-				Destroy(t.gameObject);
-
-			Destroy(ragdollRoot.gameObject);
-			boneTable.Clear();
-			targetSkeletonComponent.UpdateWorld -= UpdateSpineSkeleton;
-		}
-
-		public Rigidbody2D GetRigidbody (string boneName) {
-			var bone = skeleton.FindBone(boneName);
-			return (bone != null && boneTable.ContainsKey(bone)) ? boneTable[bone].GetComponent<Rigidbody2D>() : null;
-		}
-		#endregion
-
-		/// <summary>Generates the ragdoll simulation's Transform and joint setup.</summary>
-		void RecursivelyCreateBoneProxies (Bone b) {
-			string boneName = b.data.name;
-			if (stopBoneNames.Contains(boneName))
-				return;
-
-			var boneGameObject = new GameObject(boneName);
-			boneGameObject.layer = this.colliderLayer;
-			Transform t = boneGameObject.transform;
-			boneTable.Add(b, t);
-
-			t.parent = transform;
-			t.localPosition = new Vector3(b.WorldX, b.WorldY, 0);
-			t.localRotation = Quaternion.Euler(0, 0, b.WorldRotationX - b.shearX);
-			t.localScale = new Vector3(b.WorldScaleX, b.WorldScaleY, 0);
-
-			// MITCH: You left "todo: proper ragdoll branching"
-			var colliders = AttachBoundingBoxRagdollColliders(b, boneGameObject, skeleton, this.gravityScale);
-			if (colliders.Count == 0) {
-				float length = b.data.length;
-				if (length == 0) {
-					var circle = boneGameObject.AddComponent<CircleCollider2D>();
-					circle.radius = thickness * 0.5f;
-				} else {				
-					var box = boneGameObject.AddComponent<BoxCollider2D>();
-					box.size = new Vector2(length, thickness);
-					box.offset = new Vector2(length * 0.5f, 0); // box.center in UNITY_4
-				}
-			}
-
-			var rb = boneGameObject.GetComponent<Rigidbody2D>();
-			if (rb == null) rb = boneGameObject.AddComponent<Rigidbody2D>();
-			rb.gravityScale = this.gravityScale;
-
-			foreach (Bone child in b.Children)
-				RecursivelyCreateBoneProxies(child);
-		}
-
-		/// <summary>Performed every skeleton animation update to translate Unity Transforms positions into Spine bone transforms.</summary>
-		void UpdateSpineSkeleton (ISkeletonAnimation animatedSkeleton) {
-			bool flipX = skeleton.flipX;
-			bool flipY = skeleton.flipY;
-			bool flipXOR = flipX ^ flipY;
-			bool flipOR = flipX || flipY;
-			var startingBone = this.StartingBone;
-
-			foreach (var pair in boneTable) {
-				var b = pair.Key;
-				var t = pair.Value;
-				bool isStartingBone = (b == startingBone);
-				Transform parentTransform = isStartingBone ? ragdollRoot : boneTable[b.Parent];
-				Vector3 parentTransformWorldPosition = parentTransform.position;
-				Quaternion parentTransformWorldRotation = parentTransform.rotation;
-
-				parentSpaceHelper.position = parentTransformWorldPosition;
-				parentSpaceHelper.rotation = parentTransformWorldRotation;
-				parentSpaceHelper.localScale = parentTransform.localScale;
-
-				Vector3 boneWorldPosition = t.position;
-				Vector3 right = parentSpaceHelper.InverseTransformDirection(t.right);
-
-				Vector3 boneLocalPosition = parentSpaceHelper.InverseTransformPoint(boneWorldPosition);
-				float boneLocalRotation = Mathf.Atan2(right.y, right.x) * Mathf.Rad2Deg;
-				if (flipOR) {
-					if (isStartingBone) {
-						if (flipX) boneLocalPosition.x *= -1f;
-						if (flipY) boneLocalPosition.y *= -1f;
-
-						boneLocalRotation = boneLocalRotation * (flipXOR ? -1f : 1f);
-						if (flipX) boneLocalRotation += 180;
-					} else {
-						if (flipXOR) {
-							boneLocalRotation *= -1f;
-							boneLocalPosition.y *= -1f; // wtf??
-						}
-					}
-				}
-
-				b.x = Mathf.Lerp(b.x, boneLocalPosition.x, mix);
-				b.y = Mathf.Lerp(b.y, boneLocalPosition.y, mix);
-				b.rotation = Mathf.Lerp(b.rotation, boneLocalRotation, mix);
-				//b.AppliedRotation = Mathf.Lerp(b.AppliedRotation, boneLocalRotation, mix);
-			}
-		}
-
-		static List<Collider2D> AttachBoundingBoxRagdollColliders (Bone b, GameObject go, Skeleton skeleton, float gravityScale) {
-			const string AttachmentNameMarker = "ragdoll";
-			var colliders = new List<Collider2D>();
-			var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin;
-
-			var attachments = new List<Attachment>();
-			foreach (Slot s in skeleton.Slots) {
-				if (s.bone == b) {
-					skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(s), attachments);
-					foreach (var a in attachments) {
-						var bbAttachment = a as BoundingBoxAttachment;
-						if (bbAttachment != null) {
-							if (!a.Name.ToLower().Contains(AttachmentNameMarker))
-								continue;
-
-							var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(bbAttachment, s, go, isTrigger: false, isKinematic: false, gravityScale: gravityScale);
-							colliders.Add(bbCollider);
-						}
-					}
-				}
-			}
-
-			return colliders;
-		}
-			
-		static float GetPropagatedRotation (Bone b) {
-			Bone parent = b.Parent;
-			float a = b.AppliedRotation;
-			while (parent != null) {
-				a += parent.AppliedRotation;
-				parent = parent.parent;
-			}
-			return a;
-		}
-
-		static Vector3 FlipScale (bool flipX, bool flipY) {
-			return new Vector3(flipX ? -1f : 1f, flipY ? -1f : 1f, 1f);
-		}
-
-		#if UNITY_EDITOR
-		void OnDrawGizmosSelected () {
-			if (isActive) {
-				Gizmos.DrawWireSphere(transform.position, thickness * 1.2f);
-				Vector3 newTransformPos = RootRigidbody.position - rootOffset;
-				Gizmos.DrawLine(transform.position, newTransformPos);
-				Gizmos.DrawWireSphere(newTransformPos, thickness * 1.2f);
-			}
-		}
-		#endif
-	}
-
-}
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+// Contributed by: Mitch Thompson
+
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Spine.Unity.Modules {
+	[RequireComponent(typeof(SkeletonRenderer))]
+	public class SkeletonRagdoll2D : MonoBehaviour {
+		static Transform parentSpaceHelper;
+
+		#region Inspector
+		[Header("Hierarchy")]
+		[SpineBone]
+		public string startingBoneName = "";
+		[SpineBone]
+		public List<string> stopBoneNames = new List<string>();
+
+		[Header("Parameters")]
+		public bool applyOnStart;
+		[Tooltip("Warning!  You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")]
+		public bool disableIK = true;
+		public bool disableOtherConstraints = false;
+		[Space]
+		[Tooltip("Set RootRigidbody IsKinematic to true when Apply is called.")]
+		public bool pinStartBone;
+		public float gravityScale = 1;
+		[Tooltip("If no BoundingBox Attachment is attached to a bone, this becomes the default Width or Radius of a Bone's ragdoll Rigidbody")]
+		public float thickness = 0.125f;
+		[Tooltip("Default rotational limit value.  Min is negative this value, Max is this value.")]
+		public float rotationLimit = 20;
+		public float rootMass = 20;
+		[Tooltip("If your ragdoll seems unstable or uneffected by limits, try lowering this value.")]
+		[Range(0.01f, 1f)]
+		public float massFalloffFactor = 0.4f;
+		[Tooltip("The layer assigned to all of the rigidbody parts.")]
+		[SkeletonRagdoll.LayerField]
+		public int colliderLayer = 0;
+		[Range(0, 1)]
+		public float mix = 1;
+		#endregion
+
+		ISkeletonAnimation targetSkeletonComponent;
+		Skeleton skeleton;
+		Dictionary<Bone, Transform> boneTable = new Dictionary<Bone, Transform>();
+		Transform ragdollRoot;
+		public Rigidbody2D RootRigidbody { get; private set; }
+		public Bone StartingBone { get; private set; }
+		Vector2 rootOffset;
+		public Vector3 RootOffset { get { return this.rootOffset; } }
+		bool isActive;
+		public bool IsActive { get { return this.isActive; } }
+
+		IEnumerator Start () {
+			if (parentSpaceHelper == null) {
+				parentSpaceHelper = (new GameObject("Parent Space Helper")).transform;
+			}
+
+			targetSkeletonComponent = GetComponent<SkeletonRenderer>() as ISkeletonAnimation;
+			if (targetSkeletonComponent == null) Debug.LogError("Attached Spine component does not implement ISkeletonAnimation. This script is not compatible.");
+			skeleton = targetSkeletonComponent.Skeleton;
+
+			if (applyOnStart) {
+				yield return null;
+				Apply();
+			}
+		}
+
+		#region API
+		public Rigidbody2D[] RigidbodyArray {
+			get {
+				if (!isActive)
+					return new Rigidbody2D[0];
+
+				var rigidBodies = new Rigidbody2D[boneTable.Count];
+				int i = 0;
+				foreach (Transform t in boneTable.Values) {
+					rigidBodies[i] = t.GetComponent<Rigidbody2D>();
+					i++;
+				}
+
+				return rigidBodies;
+			}
+		}
+
+		public Vector3 EstimatedSkeletonPosition {
+			get { return this.RootRigidbody.position - rootOffset; }
+		}
+
+		/// <summary>Instantiates the ragdoll simulation and applies its transforms to the skeleton.</summary>
+		public void Apply () {
+			isActive = true;
+			mix = 1;
+
+			Bone startingBone = this.StartingBone = skeleton.FindBone(startingBoneName);
+			RecursivelyCreateBoneProxies(startingBone);
+
+			RootRigidbody = boneTable[startingBone].GetComponent<Rigidbody2D>();
+			RootRigidbody.isKinematic = pinStartBone;
+			RootRigidbody.mass = rootMass;
+			var boneColliders = new List<Collider2D>();
+			foreach (var pair in boneTable) {
+				var b = pair.Key;
+				var t = pair.Value;
+				Transform parentTransform;
+				boneColliders.Add(t.GetComponent<Collider2D>());
+				if (b == startingBone) {
+					ragdollRoot = new GameObject("RagdollRoot").transform;
+					ragdollRoot.SetParent(transform, false);
+					if (b == skeleton.RootBone) { // RagdollRoot is skeleton root.
+						ragdollRoot.localPosition = new Vector3(b.WorldX, b.WorldY, 0);
+						ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b));
+					} else {
+						ragdollRoot.localPosition = new Vector3(b.Parent.WorldX, b.Parent.WorldY, 0);
+						ragdollRoot.localRotation = Quaternion.Euler(0, 0, GetPropagatedRotation(b.Parent));
+					}
+					parentTransform = ragdollRoot;
+					rootOffset = t.position - transform.position;
+				} else {
+					parentTransform = boneTable[b.Parent];
+				}
+
+				// Add joint and attach to parent.
+				var rbParent = parentTransform.GetComponent<Rigidbody2D>();
+				if (rbParent != null) {
+					var joint = t.gameObject.AddComponent<HingeJoint2D>();
+					joint.connectedBody = rbParent;
+					Vector3 localPos = parentTransform.InverseTransformPoint(t.position);
+					joint.connectedAnchor = localPos;
+
+					joint.GetComponent<Rigidbody2D>().mass = joint.connectedBody.mass * massFalloffFactor;
+					joint.limits = new JointAngleLimits2D {
+						min = -rotationLimit,
+						max = rotationLimit
+					};
+					joint.useLimits = true;
+				}
+			}
+
+			// Ignore collisions among bones.
+			for (int x = 0; x < boneColliders.Count; x++) {
+				for (int y = 0; y < boneColliders.Count; y++) {
+					if (x == y) continue;
+					Physics2D.IgnoreCollision(boneColliders[x], boneColliders[y]);
+				}
+			}
+
+			// Destroy existing override-mode SkeletonUtility bones.
+			var utilityBones = GetComponentsInChildren<SkeletonUtilityBone>();
+			if (utilityBones.Length > 0) {
+				var destroyedUtilityBoneNames = new List<string>();
+				foreach (var ub in utilityBones) {
+					if (ub.mode == SkeletonUtilityBone.Mode.Override) {
+						destroyedUtilityBoneNames.Add(ub.gameObject.name);
+						Destroy(ub.gameObject);
+					}
+				}
+				if (destroyedUtilityBoneNames.Count > 0) {
+					string msg = "Destroyed Utility Bones: ";
+					for (int i = 0; i < destroyedUtilityBoneNames.Count; i++) {
+						msg += destroyedUtilityBoneNames[i];
+						if (i != destroyedUtilityBoneNames.Count - 1) {
+							msg += ",";
+						}
+					}
+					Debug.LogWarning(msg);
+				}
+			}
+
+			// Disable skeleton constraints.
+			if (disableIK) {
+				var ikConstraints = skeleton.IkConstraints;
+				for (int i = 0, n = ikConstraints.Count; i < n; i++)
+					ikConstraints.Items[i].mix = 0;
+			}
+
+			if (disableOtherConstraints) {
+				var transformConstraints = skeleton.transformConstraints;
+				for (int i = 0, n = transformConstraints.Count; i < n; i++) {
+					transformConstraints.Items[i].rotateMix = 0;
+					transformConstraints.Items[i].scaleMix = 0;
+					transformConstraints.Items[i].shearMix = 0;
+					transformConstraints.Items[i].translateMix = 0;
+				}
+
+				var pathConstraints = skeleton.pathConstraints;
+				for (int i = 0, n = pathConstraints.Count; i < n; i++) {
+					pathConstraints.Items[i].rotateMix = 0;
+					pathConstraints.Items[i].translateMix = 0;
+				}
+			}
+
+			targetSkeletonComponent.UpdateWorld += UpdateSpineSkeleton;
+		}
+
+		/// <summary>Transitions the mix value from the current value to a target value.</summary>
+		public Coroutine SmoothMix (float target, float duration) {
+			return StartCoroutine(SmoothMixCoroutine(target, duration));
+		}
+
+		IEnumerator SmoothMixCoroutine (float target, float duration) {
+			float startTime = Time.time;
+			float startMix = mix;
+			while (mix > 0) {
+				skeleton.SetBonesToSetupPose();
+				mix = Mathf.SmoothStep(startMix, target, (Time.time - startTime) / duration);
+				yield return null;
+			}
+		}
+
+		/// <summary>Set the transform world position while preserving the ragdoll parts world position.</summary>
+		public void SetSkeletonPosition (Vector3 worldPosition) {
+			if (!isActive) {
+				Debug.LogWarning("Can't call SetSkeletonPosition while Ragdoll is not active!");
+				return;
+			}
+
+			Vector3 offset = worldPosition - transform.position;
+			transform.position = worldPosition;
+			foreach (Transform t in boneTable.Values)
+				t.position -= offset;
+
+			UpdateSpineSkeleton(null);
+			skeleton.UpdateWorldTransform();
+		}
+
+		/// <summary>Removes the ragdoll instance and effect from the animated skeleton.</summary>
+		public void Remove () {
+			isActive = false;
+			foreach (var t in boneTable.Values)
+				Destroy(t.gameObject);
+
+			Destroy(ragdollRoot.gameObject);
+			boneTable.Clear();
+			targetSkeletonComponent.UpdateWorld -= UpdateSpineSkeleton;
+		}
+
+		public Rigidbody2D GetRigidbody (string boneName) {
+			var bone = skeleton.FindBone(boneName);
+			return (bone != null && boneTable.ContainsKey(bone)) ? boneTable[bone].GetComponent<Rigidbody2D>() : null;
+		}
+		#endregion
+
+		/// <summary>Generates the ragdoll simulation's Transform and joint setup.</summary>
+		void RecursivelyCreateBoneProxies (Bone b) {
+			string boneName = b.data.name;
+			if (stopBoneNames.Contains(boneName))
+				return;
+
+			var boneGameObject = new GameObject(boneName);
+			boneGameObject.layer = this.colliderLayer;
+			Transform t = boneGameObject.transform;
+			boneTable.Add(b, t);
+
+			t.parent = transform;
+			t.localPosition = new Vector3(b.WorldX, b.WorldY, 0);
+			t.localRotation = Quaternion.Euler(0, 0, b.WorldRotationX - b.shearX);
+			t.localScale = new Vector3(b.WorldScaleX, b.WorldScaleY, 0);
+
+			// MITCH: You left "todo: proper ragdoll branching"
+			var colliders = AttachBoundingBoxRagdollColliders(b, boneGameObject, skeleton, this.gravityScale);
+			if (colliders.Count == 0) {
+				float length = b.data.length;
+				if (length == 0) {
+					var circle = boneGameObject.AddComponent<CircleCollider2D>();
+					circle.radius = thickness * 0.5f;
+				} else {				
+					var box = boneGameObject.AddComponent<BoxCollider2D>();
+					box.size = new Vector2(length, thickness);
+					box.offset = new Vector2(length * 0.5f, 0); // box.center in UNITY_4
+				}
+			}
+
+			var rb = boneGameObject.GetComponent<Rigidbody2D>();
+			if (rb == null) rb = boneGameObject.AddComponent<Rigidbody2D>();
+			rb.gravityScale = this.gravityScale;
+
+			foreach (Bone child in b.Children)
+				RecursivelyCreateBoneProxies(child);
+		}
+
+		/// <summary>Performed every skeleton animation update to translate Unity Transforms positions into Spine bone transforms.</summary>
+		void UpdateSpineSkeleton (ISkeletonAnimation animatedSkeleton) {
+			bool flipX = skeleton.flipX;
+			bool flipY = skeleton.flipY;
+			bool flipXOR = flipX ^ flipY;
+			bool flipOR = flipX || flipY;
+			var startingBone = this.StartingBone;
+
+			foreach (var pair in boneTable) {
+				var b = pair.Key;
+				var t = pair.Value;
+				bool isStartingBone = (b == startingBone);
+				Transform parentTransform = isStartingBone ? ragdollRoot : boneTable[b.Parent];
+				Vector3 parentTransformWorldPosition = parentTransform.position;
+				Quaternion parentTransformWorldRotation = parentTransform.rotation;
+
+				parentSpaceHelper.position = parentTransformWorldPosition;
+				parentSpaceHelper.rotation = parentTransformWorldRotation;
+				parentSpaceHelper.localScale = parentTransform.localScale;
+
+				Vector3 boneWorldPosition = t.position;
+				Vector3 right = parentSpaceHelper.InverseTransformDirection(t.right);
+
+				Vector3 boneLocalPosition = parentSpaceHelper.InverseTransformPoint(boneWorldPosition);
+				float boneLocalRotation = Mathf.Atan2(right.y, right.x) * Mathf.Rad2Deg;
+				if (flipOR) {
+					if (isStartingBone) {
+						if (flipX) boneLocalPosition.x *= -1f;
+						if (flipY) boneLocalPosition.y *= -1f;
+
+						boneLocalRotation = boneLocalRotation * (flipXOR ? -1f : 1f);
+						if (flipX) boneLocalRotation += 180;
+					} else {
+						if (flipXOR) {
+							boneLocalRotation *= -1f;
+							boneLocalPosition.y *= -1f; // wtf??
+						}
+					}
+				}
+
+				b.x = Mathf.Lerp(b.x, boneLocalPosition.x, mix);
+				b.y = Mathf.Lerp(b.y, boneLocalPosition.y, mix);
+				b.rotation = Mathf.Lerp(b.rotation, boneLocalRotation, mix);
+				//b.AppliedRotation = Mathf.Lerp(b.AppliedRotation, boneLocalRotation, mix);
+			}
+		}
+
+		static List<Collider2D> AttachBoundingBoxRagdollColliders (Bone b, GameObject go, Skeleton skeleton, float gravityScale) {
+			const string AttachmentNameMarker = "ragdoll";
+			var colliders = new List<Collider2D>();
+			var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin;
+
+			var attachments = new List<Attachment>();
+			foreach (Slot s in skeleton.Slots) {
+				if (s.bone == b) {
+					skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(s), attachments);
+					foreach (var a in attachments) {
+						var bbAttachment = a as BoundingBoxAttachment;
+						if (bbAttachment != null) {
+							if (!a.Name.ToLower().Contains(AttachmentNameMarker))
+								continue;
+
+							var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(bbAttachment, s, go, isTrigger: false, isKinematic: false, gravityScale: gravityScale);
+							colliders.Add(bbCollider);
+						}
+					}
+				}
+			}
+
+			return colliders;
+		}
+
+		static float GetPropagatedRotation (Bone b) {
+			Bone parent = b.Parent;
+			float a = b.AppliedRotation;
+			while (parent != null) {
+				a += parent.AppliedRotation;
+				parent = parent.parent;
+			}
+			return a;
+		}
+
+		static Vector3 FlipScale (bool flipX, bool flipY) {
+			return new Vector3(flipX ? -1f : 1f, flipY ? -1f : 1f, 1f);
+		}
+
+		#if UNITY_EDITOR
+		void OnDrawGizmosSelected () {
+			if (isActive) {
+				Gizmos.DrawWireSphere(transform.position, thickness * 1.2f);
+				Vector3 newTransformPos = RootRigidbody.position - rootOffset;
+				Gizmos.DrawLine(transform.position, newTransformPos);
+				Gizmos.DrawWireSphere(newTransformPos, thickness * 1.2f);
+			}
+		}
+		#endif
+	}
+
+}

+ 1 - 1
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc

@@ -26,7 +26,7 @@ struct VertexInput
 #if defined(_NORMALMAP)
 	float4 tangent : TANGENT;
 #endif // _NORMALMAP
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 
 ////////////////////////////////////////

+ 1 - 1
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc

@@ -12,7 +12,7 @@ struct VertexInput
 	float4 vertex : POSITION;
 	float4 texcoord : TEXCOORD0;
 	fixed4 color : COLOR;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 
 struct VertexOutput

+ 3 - 3
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader

@@ -286,7 +286,7 @@ struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
     fixed4 color : COLOR;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -327,7 +327,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -370,7 +370,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;

+ 3 - 3
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader

@@ -283,7 +283,7 @@ struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
     fixed4 color : COLOR;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -324,7 +324,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -367,7 +367,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;

+ 3 - 3
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader

@@ -286,7 +286,7 @@ struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
     fixed4 color : COLOR;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -327,7 +327,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;
@@ -370,7 +370,7 @@ struct appdata {
     float3 normal : NORMAL;
     fixed4 color : COLOR;
     float4 texcoord : TEXCOORD0;
-	UNITY_INSTANCE_ID
+	UNITY_VERTEX_INPUT_INSTANCE_ID
 };
 v2f vert( appdata v ) {
 	v2f o;

+ 0 - 2
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc

@@ -1,5 +1,3 @@
-// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
-
 #ifndef SHADER_SHARED_INCLUDED
 #define SHADER_SHARED_INCLUDED
 

+ 0 - 2
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader

@@ -1,5 +1,3 @@
-// Upgrade NOTE: replaced 'UNITY_INSTANCE_ID' with 'UNITY_VERTEX_INPUT_INSTANCE_ID'
-
 Shader "Hidden/Internal-SpriteDepthNormalsTexture" {
 
 // Use this shader to render a DepthNormals texture for a camera with correct sprite normals (using camera.RenderWithShader)

+ 2 - 2
spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc

@@ -323,8 +323,8 @@ VertexOutput vert(VertexInput input)
 	output.pos = calculateLocalPos(input.vertex);
 	output.color = calculateVertexColor(input.color);
 	output.texcoord = float3(calculateTextureCoord(input.texcoord), 0);
-	
-	float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex);
+
+	float3 viewPos = UnityObjectToViewPos(input.vertex);
 
 #if defined(PER_PIXEL_LIGHTING)
 	

+ 28 - 10
spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader

@@ -15,6 +15,8 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
 		_StencilReadMask ("Stencil Read Mask", Float) = 255
 
 		_ColorMask ("Color Mask", Float) = 15
+
+		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
 	}
 
 	SubShader
@@ -50,9 +52,11 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
 		CGPROGRAM
 			#pragma vertex vert
 			#pragma fragment frag
+
 			#include "UnityCG.cginc"
-			fixed4 _Color;
-			fixed4 _Black;
+			#include "UnityUI.cginc"
+
+			#pragma multi_compile __ UNITY_UI_ALPHACLIP
 
 			struct VertexInput {
 				float4 vertex   : POSITION;
@@ -60,6 +64,7 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
 				float2 texcoord : TEXCOORD0;
 				float2 uv1 : TEXCOORD1;
 				float2 uv2 : TEXCOORD2;
+				UNITY_VERTEX_INPUT_INSTANCE_ID
 			};
 
 			struct VertexOutput {
@@ -68,17 +73,24 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
 				half2 texcoord  : TEXCOORD0;
 				float2 uv1 : TEXCOORD1;
 				float2 uv2 : TEXCOORD2;
+				float4 worldPosition : TEXCOORD3;
+				UNITY_VERTEX_OUTPUT_STEREO
 			};
-			
+
+			fixed4 _Color;
+			fixed4 _Black;
+			fixed4 _TextureSampleAdd;
+			float4 _ClipRect;
 
 			VertexOutput vert (VertexInput IN) {
 				VertexOutput OUT;
-				OUT.vertex = UnityObjectToClipPos(IN.vertex);
-				OUT.texcoord = IN.texcoord;
 
-				#ifdef UNITY_HALF_TEXEL_OFFSET
-				OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1);
-				#endif
+				UNITY_SETUP_INSTANCE_ID(IN);
+				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
+
+				OUT.worldPosition = IN.vertex;
+				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
+				OUT.texcoord = IN.texcoord;
 
 				OUT.color = IN.color * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor.
 				OUT.uv1 = IN.uv1;
@@ -90,8 +102,14 @@ Shader "Spine/SkeletonGraphic Tint Black (Premultiply Alpha)"
 
 			fixed4 frag (VertexOutput IN) : SV_Target
 			{
-				float4 texColor = tex2D(_MainTex, IN.texcoord);
-				//clip(color.a - 0.01);
+				half4 texColor = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
+
+				texColor.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
+
+				#ifdef UNITY_UI_ALPHACLIP
+				clip (texColor.a - 0.001);
+				#endif
+
 				return (texColor * IN.color) + float4(((1-texColor.rgb) * texColor.a * (_Black.rgb + float3(IN.uv1.r, IN.uv1.g, IN.uv2.r))), 0);
 			}
 		ENDCG

+ 29 - 6
spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader

@@ -1,4 +1,4 @@
-// This is a premultiply-alpha adaptation of the built-in Unity shader "UI/Default" to allow Unity UI stencil masking.
+// This is a premultiply-alpha adaptation of the built-in Unity shader "UI/Default" in Unity 5.6.2 to allow Unity UI stencil masking.
 
 Shader "Spine/SkeletonGraphic (Premultiply Alpha)"
 {
@@ -14,6 +14,8 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)"
 		_StencilReadMask ("Stencil Read Mask", Float) = 255
 
 		_ColorMask ("Color Mask", Float) = 15
+
+		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
 	}
 
 	SubShader
@@ -49,25 +51,40 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)"
 		CGPROGRAM
 			#pragma vertex vert
 			#pragma fragment frag
+			#pragma target 2.0
+
 			#include "UnityCG.cginc"
-			fixed4 _Color;
+			#include "UnityUI.cginc"
+
+			#pragma multi_compile __ UNITY_UI_ALPHACLIP
 
 			struct VertexInput {
 				float4 vertex   : POSITION;
 				float4 color    : COLOR;
 				float2 texcoord : TEXCOORD0;
+				UNITY_VERTEX_INPUT_INSTANCE_ID
 			};
 
 			struct VertexOutput {
 				float4 vertex   : SV_POSITION;
 				fixed4 color    : COLOR;
 				half2 texcoord  : TEXCOORD0;
+				float4 worldPosition : TEXCOORD1;
+				UNITY_VERTEX_OUTPUT_STEREO
 			};
-			
+
+			fixed4 _Color;
+			fixed4 _TextureSampleAdd;
+			float4 _ClipRect;
 
 			VertexOutput vert (VertexInput IN) {
 				VertexOutput OUT;
-				OUT.vertex = UnityObjectToClipPos(IN.vertex);
+
+				UNITY_SETUP_INSTANCE_ID(IN);
+				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
+
+				OUT.worldPosition = IN.vertex;
+				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
 				OUT.texcoord = IN.texcoord;
 
 				#ifdef UNITY_HALF_TEXEL_OFFSET
@@ -82,8 +99,14 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)"
 
 			fixed4 frag (VertexOutput IN) : SV_Target
 			{
-				half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
-				//clip(color.a - 0.01);
+				half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
+
+				color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
+
+				#ifdef UNITY_UI_ALPHACLIP
+				clip (color.a - 0.001);
+				#endif
+
 				return color;
 			}
 		ENDCG

+ 0 - 2
spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader

@@ -1,5 +1,3 @@
-// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
-
 Shader "Hidden/Spine/Bones" {
 Properties {
 	_Color ("Color", Color) = (0.5,0.5,0.5,0.5)

+ 1 - 1
spine-unity/Assets/spine-unity/SkeletonAnimation.cs

@@ -126,7 +126,7 @@ namespace Spine.Unity {
 		}
 		#endregion
 
-		protected override void ClearState () {
+		public override void ClearState () {
 			base.ClearState();
 			if (state != null) state.ClearTracks();
 		}

+ 1 - 1
spine-unity/Assets/spine-unity/SkeletonRenderer.cs

@@ -149,7 +149,7 @@ namespace Spine.Unity {
 			rendererBuffers.Dispose();
 		}
 
-		protected virtual void ClearState () {
+		public virtual void ClearState () {
 			meshFilter.sharedMesh = null;
 			currentInstructions.Clear();
 			if (skeleton != null) skeleton.SetToSetupPose();

+ 4 - 4
spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs

@@ -38,7 +38,7 @@ namespace Spine.Unity {
 	[RequireComponent(typeof(ISkeletonAnimation))]
 	[ExecuteInEditMode]
 	public class SkeletonUtility : MonoBehaviour {
-	
+
 		#region BoundingBoxAttachment
 		public static PolygonCollider2D AddBoundingBoxGameObject (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) {
 			Skin skin = string.IsNullOrEmpty(skinName) ? skeleton.data.defaultSkin : skeleton.data.FindSkin(skinName);
@@ -225,7 +225,7 @@ namespace Spine.Unity {
 				var ikConstraints = skeleton.IkConstraints;
 				for (int i = 0, n = ikConstraints.Count; i < n; i++)
 					constraintTargets.Add(ikConstraints.Items[i].target);
-				
+
 				var transformConstraints = skeleton.TransformConstraints;
 				for (int i = 0, n = transformConstraints.Count; i < n; i++)
 					constraintTargets.Add(transformConstraints.Items[i].target);
@@ -246,7 +246,7 @@ namespace Spine.Unity {
 
 					if (hasTransformBones || hasUtilityConstraints)
 						skeletonAnimation.UpdateWorld += UpdateWorld;
-					
+
 					if (hasUtilityConstraints)
 						skeletonAnimation.UpdateComplete += UpdateComplete;
 				}
@@ -283,7 +283,7 @@ namespace Spine.Unity {
 		void UpdateAllBones () {
 			if (boneRoot == null)
 				CollectBones();
-				
+
 			var utilityBones = this.utilityBones;
 			if (utilityBones == null) return;
 			for (int i = 0, n = utilityBones.Count; i < n; i++)