From 216441ac4a4e1517ce7bfdbabc4de6f40308fdf1 Mon Sep 17 00:00:00 2001 From: pharan Date: Thu, 29 Jun 2017 17:14:27 +0800 Subject: [PATCH 1/5] [unity] Cleanup line endings. --- .../Editor/SpineAttributeDrawers.cs | 3 +- .../Modules/Ragdoll/SkeletonRagdoll2D.cs | 820 +++++++++--------- .../Assets/spine-unity/SkeletonAnimation.cs | 2 +- .../Assets/spine-unity/SkeletonRenderer.cs | 2 +- .../SkeletonUtility/SkeletonUtility.cs | 8 +- 5 files changed, 418 insertions(+), 417 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs b/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs index 82bb77b14..505a31ae0 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs +++ b/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)) diff --git a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs b/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs index 3558ee1d7..0e9c0aba2 100644 --- a/spine-unity/Assets/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs +++ b/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 stopBoneNames = new List(); - - [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 boneTable = new Dictionary(); - 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() 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(); - i++; - } - - return rigidBodies; - } - } - - public Vector3 EstimatedSkeletonPosition { - get { return this.RootRigidbody.position - rootOffset; } - } - - /// Instantiates the ragdoll simulation and applies its transforms to the skeleton. - public void Apply () { - isActive = true; - mix = 1; - - Bone startingBone = this.StartingBone = skeleton.FindBone(startingBoneName); - RecursivelyCreateBoneProxies(startingBone); - - RootRigidbody = boneTable[startingBone].GetComponent(); - RootRigidbody.isKinematic = pinStartBone; - RootRigidbody.mass = rootMass; - var boneColliders = new List(); - foreach (var pair in boneTable) { - var b = pair.Key; - var t = pair.Value; - Transform parentTransform; - boneColliders.Add(t.GetComponent()); - 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(); - if (rbParent != null) { - var joint = t.gameObject.AddComponent(); - joint.connectedBody = rbParent; - Vector3 localPos = parentTransform.InverseTransformPoint(t.position); - joint.connectedAnchor = localPos; - - joint.GetComponent().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(); - if (utilityBones.Length > 0) { - var destroyedUtilityBoneNames = new List(); - 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; - } - - /// Transitions the mix value from the current value to a target value. - 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; - } - } - - /// Set the transform world position while preserving the ragdoll parts world position. - 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(); - } - - /// Removes the ragdoll instance and effect from the animated skeleton. - 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() : null; - } - #endregion - - /// Generates the ragdoll simulation's Transform and joint setup. - 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(); - circle.radius = thickness * 0.5f; - } else { - var box = boneGameObject.AddComponent(); - box.size = new Vector2(length, thickness); - box.offset = new Vector2(length * 0.5f, 0); // box.center in UNITY_4 - } - } - - var rb = boneGameObject.GetComponent(); - if (rb == null) rb = boneGameObject.AddComponent(); - rb.gravityScale = this.gravityScale; - - foreach (Bone child in b.Children) - RecursivelyCreateBoneProxies(child); - } - - /// Performed every skeleton animation update to translate Unity Transforms positions into Spine bone transforms. - 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 AttachBoundingBoxRagdollColliders (Bone b, GameObject go, Skeleton skeleton, float gravityScale) { - const string AttachmentNameMarker = "ragdoll"; - var colliders = new List(); - var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin; - - var attachments = new List(); - 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 stopBoneNames = new List(); + + [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 boneTable = new Dictionary(); + 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() 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(); + i++; + } + + return rigidBodies; + } + } + + public Vector3 EstimatedSkeletonPosition { + get { return this.RootRigidbody.position - rootOffset; } + } + + /// Instantiates the ragdoll simulation and applies its transforms to the skeleton. + public void Apply () { + isActive = true; + mix = 1; + + Bone startingBone = this.StartingBone = skeleton.FindBone(startingBoneName); + RecursivelyCreateBoneProxies(startingBone); + + RootRigidbody = boneTable[startingBone].GetComponent(); + RootRigidbody.isKinematic = pinStartBone; + RootRigidbody.mass = rootMass; + var boneColliders = new List(); + foreach (var pair in boneTable) { + var b = pair.Key; + var t = pair.Value; + Transform parentTransform; + boneColliders.Add(t.GetComponent()); + 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(); + if (rbParent != null) { + var joint = t.gameObject.AddComponent(); + joint.connectedBody = rbParent; + Vector3 localPos = parentTransform.InverseTransformPoint(t.position); + joint.connectedAnchor = localPos; + + joint.GetComponent().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(); + if (utilityBones.Length > 0) { + var destroyedUtilityBoneNames = new List(); + 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; + } + + /// Transitions the mix value from the current value to a target value. + 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; + } + } + + /// Set the transform world position while preserving the ragdoll parts world position. + 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(); + } + + /// Removes the ragdoll instance and effect from the animated skeleton. + 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() : null; + } + #endregion + + /// Generates the ragdoll simulation's Transform and joint setup. + 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(); + circle.radius = thickness * 0.5f; + } else { + var box = boneGameObject.AddComponent(); + box.size = new Vector2(length, thickness); + box.offset = new Vector2(length * 0.5f, 0); // box.center in UNITY_4 + } + } + + var rb = boneGameObject.GetComponent(); + if (rb == null) rb = boneGameObject.AddComponent(); + rb.gravityScale = this.gravityScale; + + foreach (Bone child in b.Children) + RecursivelyCreateBoneProxies(child); + } + + /// Performed every skeleton animation update to translate Unity Transforms positions into Spine bone transforms. + 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 AttachBoundingBoxRagdollColliders (Bone b, GameObject go, Skeleton skeleton, float gravityScale) { + const string AttachmentNameMarker = "ragdoll"; + var colliders = new List(); + var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin; + + var attachments = new List(); + 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 + } + +} diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs index 7296c4616..f69546429 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs +++ b/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(); } diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index a643a5c28..78b114194 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/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(); diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs index b44cb5306..9765e4b66 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs +++ b/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++) From f1aa76570f1a09d51bbf983eab36bb91dd74fde5 Mon Sep 17 00:00:00 2001 From: pharan Date: Thu, 29 Jun 2017 17:14:55 +0800 Subject: [PATCH 2/5] [unity] Updated shaders to Unity 5.6. --- .../Sprite/CGIncludes/SpriteLighting.cginc | 2 +- .../Sprite/CGIncludes/SpriteUnlit.cginc | 2 +- .../Sprite/CameraDepthNormalsTexture.shader | 6 +-- .../Shaders/Sprite/CameraDepthTexture.shader | 6 +-- .../Sprite/CameraNormalsTexture.shader | 6 +-- .../Modules/Shaders/Sprite/ShaderShared.cginc | 2 - .../Sprite/SpriteDepthNormalsTexture.shader | 2 - .../Shaders/Sprite/SpriteVertexLighting.cginc | 4 +- .../Spine-SkeletonGraphic-TintBlack.shader | 38 ++++++++++++++----- .../Shaders/Spine-SkeletonGraphic.shader | 35 ++++++++++++++--- .../Shaders/Utility/Hidden-Spine-Bones.shader | 2 - 11 files changed, 70 insertions(+), 35 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc index f2e5f1366..018ca93cd 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteLighting.cginc +++ b/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 }; //////////////////////////////////////// diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc index 0a40e5b64..4385ffcc5 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc +++ b/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 diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader index 5de9bae59..0c80ebc3e 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthNormalsTexture.shader +++ b/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; diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader index ecf76e1d8..3a7f60d55 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraDepthTexture.shader +++ b/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; diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader index 2f26ff033..1cf6a7778 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/CameraNormalsTexture.shader +++ b/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; diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc index 8fbd5934c..65d6f274d 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/ShaderShared.cginc +++ b/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 diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader index 5c164e8f6..4d834a267 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteDepthNormalsTexture.shader +++ b/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) diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc b/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc index e985daf2a..aae3b2771 100644 --- a/spine-unity/Assets/spine-unity/Modules/Shaders/Sprite/SpriteVertexLighting.cginc +++ b/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) diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader index 0976edd75..b45e14749 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic-TintBlack.shader +++ b/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 diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader index f09740549..66dd907a2 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader +++ b/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 diff --git a/spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader b/spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader index 76887ac41..ee2045d4c 100644 --- a/spine-unity/Assets/spine-unity/Shaders/Utility/Hidden-Spine-Bones.shader +++ b/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) From dac38e584391383a0e46286d7d2ca798fb2646ca Mon Sep 17 00:00:00 2001 From: John Date: Mon, 3 Jul 2017 17:15:13 +0800 Subject: [PATCH 3/5] [unity] Allow overwrite initialize + logs. --- .../BoundingBoxFollower.cs | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs b/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs index 2e5820c12..dbed7f565 100644 --- a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs +++ b/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs @@ -79,7 +79,7 @@ namespace Spine.Unity { /// /// 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. - 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. && @@ -119,7 +121,7 @@ namespace Spine.Unity { 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); + 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); @@ -206,13 +208,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]; } } From 263c6278e253322b40f2347b9e5ef2513afca45f Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Jul 2017 08:57:38 +0800 Subject: [PATCH 4/5] [unity] BoundingBoxFollower also uses active skin. --- .../BoundingBoxFollower.cs | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs b/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs index dbed7f565..74c7029df 100644 --- a/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs +++ b/spine-unity/Assets/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs @@ -112,27 +112,10 @@ namespace Spine.Unity { } if (this.gameObject.activeInHierarchy) { - foreach (var skin in skeleton.Data.Skins) { - var attachmentNames = new List(); - skin.FindNamesForSlot(slotIndex, attachmentNames); + foreach (var skin in skeleton.Data.Skins) + AddSkin(skin, skeleton, slotIndex); - 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); - } - } - } + AddSkin(skeleton.skin, skeleton, slotIndex); } if (BoundingBoxFollower.DebugMessages) { @@ -146,6 +129,28 @@ namespace Spine.Unity { } } + void AddSkin (Skin skin, Skeleton skeleton, int slotIndex) { + var attachmentNames = new List(); + 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(); From 8b14b18fdaa55acb3cfaea33c85da1393a5b65c6 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 4 Jul 2017 10:33:16 +0200 Subject: [PATCH 5/5] [c] Ported fix for DeformTimeline, see #932 --- spine-c/spine-c/src/spine/Animation.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index 51771caeb..0c2c7194f 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/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; }