diff --git a/spine-unity/Assets/Examples/Scenes/Ragdoll.unity b/spine-unity/Assets/Examples/Scenes/Ragdoll.unity index b35ed7554..2403edf40 100644 Binary files a/spine-unity/Assets/Examples/Scenes/Ragdoll.unity and b/spine-unity/Assets/Examples/Scenes/Ragdoll.unity differ diff --git a/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs b/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs deleted file mode 100644 index bfaa254e7..000000000 --- a/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** - * Spine Runtimes Software License - * Version 2.3 - * - * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the - * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) 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. - *****************************************************************************/ - -using UnityEngine; -using System.Collections; - -public class DynamicSpineBone : MonoBehaviour { - - public Transform speedReference; - - [SpineBone] - public string boneName; - - [Range(-90, 90)] - public float minRotation = -45; - [Range(-90, 90)] - public float maxRotation = 45; - - [Range(-2000, 2000)] - public float rotationFactor = 300; - - [Range(5, 30)] - public float returnSpeed = 10; - - [Range(100, 1000)] - public float boneSpeed = 300; - - public float returnThreshhold = 0.01f; - - public bool useAcceleration; - - - SkeletonAnimation skeletonAnimation; - float goalRotation; - Spine.Bone bone; - Vector3 velocity; - Vector3 acceleration; - Vector3 lastPosition; - - void Start() { - if (speedReference == null) - speedReference = transform; - - skeletonAnimation = GetComponent(); - bone = SpineBone.GetBone(boneName, skeletonAnimation); - skeletonAnimation.UpdateLocal += UpdateLocal; - lastPosition = speedReference.position; - } - - void FixedUpdate() { - acceleration = (speedReference.position - lastPosition) - velocity; - velocity = speedReference.position - lastPosition; - lastPosition = speedReference.position; - } - - void UpdateLocal(SkeletonRenderer renderer) { - Vector3 vec = useAcceleration ? acceleration : velocity; - - if (Mathf.Abs(vec.x) < returnThreshhold) - goalRotation = Mathf.Lerp(goalRotation, 0, returnSpeed * Time.deltaTime); - else - goalRotation += vec.x * rotationFactor * Time.deltaTime * (bone.WorldFlipX ? -1 : 1); - - goalRotation = Mathf.Clamp(goalRotation, minRotation, maxRotation); - - bone.Rotation = Mathf.Lerp(bone.Rotation, bone.Rotation + goalRotation, boneSpeed * Time.deltaTime); - - } -} diff --git a/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs.meta b/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs.meta deleted file mode 100644 index bc05f26e6..000000000 --- a/spine-unity/Assets/Examples/Scripts/DynamicSpineBone.cs.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 7dae3f4db9a24bf4abe2059526bfd689 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs b/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs index eea04f694..f15e773fc 100644 --- a/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs +++ b/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs @@ -48,7 +48,6 @@ public class RaggedySpineboy : MonoBehaviour { Vector3 estimatedPos = ragdoll.EstimatedSkeletonPosition; Vector3 rbPosition = ragdoll.RootRigidbody.position; - Ray ray = new Ray(rbPosition, estimatedPos - rbPosition); Vector3 skeletonPoint = estimatedPos; RaycastHit2D hit = Physics2D.Raycast((Vector2)rbPosition, (Vector2)(estimatedPos - rbPosition), Vector3.Distance(estimatedPos, rbPosition), groundMask); if (hit.collider != null) @@ -69,7 +68,7 @@ public class RaggedySpineboy : MonoBehaviour { float t = 0; while (t < 0.5f) { - if (ragdoll.RootRigidbody.velocity.magnitude > 0.06f) + if (ragdoll.RootRigidbody.velocity.magnitude > 0.09f) t = 0; else t += Time.deltaTime; diff --git a/spine-unity/Assets/Examples/Spine/Raggedy Spineboy.prefab b/spine-unity/Assets/Examples/Spine/Raggedy Spineboy.prefab index 618b8cd95..3828cb89e 100644 Binary files a/spine-unity/Assets/Examples/Spine/Raggedy Spineboy.prefab and b/spine-unity/Assets/Examples/Spine/Raggedy Spineboy.prefab differ diff --git a/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs b/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs index f059aae31..87c3da693 100644 --- a/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs +++ b/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdoll2DInspector.cs @@ -10,20 +10,21 @@ using System.Collections.Generic; [CustomEditor(typeof(SkeletonRagdoll2D))] public class SkeletonRagdoll2DInspector : Editor { - SerializedProperty startingBoneName, stopBoneNames, applyOnStart, pinStartBone, enableJointCollision, gravityScale, disableIK, defaultThickness, rotationLimit, colliderLayer, mix; + SerializedProperty startingBoneName, stopBoneNames, applyOnStart, pinStartBone, enableJointCollision, gravityScale, disableIK, thickness, rotationLimit, colliderLayer, mix, rootMass, massFalloffFactor; void OnEnable () { startingBoneName = serializedObject.FindProperty("startingBoneName"); stopBoneNames = serializedObject.FindProperty("stopBoneNames"); applyOnStart = serializedObject.FindProperty("applyOnStart"); pinStartBone = serializedObject.FindProperty("pinStartBone"); - enableJointCollision = serializedObject.FindProperty("enableJointCollision"); gravityScale = serializedObject.FindProperty("gravityScale"); disableIK = serializedObject.FindProperty("disableIK"); - defaultThickness = serializedObject.FindProperty("defaultThickness"); + thickness = serializedObject.FindProperty("thickness"); rotationLimit = serializedObject.FindProperty("rotationLimit"); colliderLayer = serializedObject.FindProperty("colliderLayer"); mix = serializedObject.FindProperty("mix"); + rootMass = serializedObject.FindProperty("rootMass"); + massFalloffFactor = serializedObject.FindProperty("massFalloffFactor"); } public override void OnInspectorGUI () { @@ -31,13 +32,15 @@ public class SkeletonRagdoll2DInspector : Editor { EditorGUILayout.PropertyField(stopBoneNames, true); EditorGUILayout.PropertyField(applyOnStart); EditorGUILayout.PropertyField(pinStartBone); - EditorGUILayout.PropertyField(enableJointCollision); EditorGUILayout.PropertyField(gravityScale); EditorGUILayout.PropertyField(disableIK); - EditorGUILayout.PropertyField(defaultThickness); + EditorGUILayout.PropertyField(thickness); EditorGUILayout.PropertyField(rotationLimit); + EditorGUILayout.PropertyField(rootMass); + EditorGUILayout.PropertyField(massFalloffFactor); colliderLayer.intValue = EditorGUILayout.LayerField(colliderLayer.displayName, colliderLayer.intValue); EditorGUILayout.PropertyField(mix); + serializedObject.ApplyModifiedProperties(); } diff --git a/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdollInspector.cs b/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdollInspector.cs index a92f570e2..af1627af4 100644 --- a/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdollInspector.cs +++ b/spine-unity/Assets/spine-unity/Ragdoll/Editor/SkeletonRagdollInspector.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; [CustomEditor(typeof(SkeletonRagdoll))] public class SkeletonRagdollInspector : Editor { - SerializedProperty startingBoneName, stopBoneNames, applyOnStart, pinStartBone, enableJointCollision, useGravity, disableIK, defaultThickness, rotationLimit, colliderLayer, mix; + SerializedProperty startingBoneName, stopBoneNames, applyOnStart, pinStartBone, enableJointCollision, useGravity, disableIK, thickness, rotationLimit, colliderLayer, mix, rootMass, massFalloffFactor; void OnEnable () { startingBoneName = serializedObject.FindProperty("startingBoneName"); @@ -20,10 +20,12 @@ public class SkeletonRagdollInspector : Editor { enableJointCollision = serializedObject.FindProperty("enableJointCollision"); useGravity = serializedObject.FindProperty("useGravity"); disableIK = serializedObject.FindProperty("disableIK"); - defaultThickness = serializedObject.FindProperty("defaultThickness"); + thickness = serializedObject.FindProperty("thickness"); rotationLimit = serializedObject.FindProperty("rotationLimit"); colliderLayer = serializedObject.FindProperty("colliderLayer"); mix = serializedObject.FindProperty("mix"); + rootMass = serializedObject.FindProperty("rootMass"); + massFalloffFactor = serializedObject.FindProperty("massFalloffFactor"); } public override void OnInspectorGUI () { @@ -34,8 +36,10 @@ public class SkeletonRagdollInspector : Editor { EditorGUILayout.PropertyField(enableJointCollision); EditorGUILayout.PropertyField(useGravity); EditorGUILayout.PropertyField(disableIK); - EditorGUILayout.PropertyField(defaultThickness); + EditorGUILayout.PropertyField(thickness); EditorGUILayout.PropertyField(rotationLimit); + EditorGUILayout.PropertyField(rootMass); + EditorGUILayout.PropertyField(massFalloffFactor); colliderLayer.intValue = EditorGUILayout.LayerField(colliderLayer.displayName, colliderLayer.intValue); EditorGUILayout.PropertyField(mix); diff --git a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll.cs b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll.cs index ac43ad1cd..24cb9f6c1 100644 --- a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll.cs +++ b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll.cs @@ -28,9 +28,13 @@ public class SkeletonRagdoll : MonoBehaviour { [Tooltip("Warning! You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")] public bool disableIK = true; [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 defaultThickness = 0.125f; + 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.")] public int colliderLayer = 0; [Range(0, 1)] @@ -106,6 +110,34 @@ public class SkeletonRagdoll : MonoBehaviour { foreach (Transform t in boneTable.Values) { t.position -= offset; } + + UpdateWorld(null); + skeleton.UpdateWorldTransform(); + } + + public Rigidbody[] GetRigidbodyArray () { + if (!isActive) + return new Rigidbody[0]; + + Rigidbody[] arr = new Rigidbody[boneTable.Count]; + int i = 0; + foreach(Transform t in boneTable.Values){ + arr[i] = t.GetComponent(); + i++; + } + + return arr; + } + + public Rigidbody GetRigidbody (string boneName) { + var bone = skeleton.FindBone(boneName); + if (bone == null) + return null; + + if (boneTable.ContainsKey(bone)) + return boneTable[bone].GetComponent(); + + return null; } public void Remove () { @@ -131,6 +163,8 @@ public class SkeletonRagdoll : MonoBehaviour { rootRigidbody = boneTable[ragdollRootBone].GetComponent(); rootRigidbody.isKinematic = pinStartBone; + rootRigidbody.mass = rootMass; + List boneColliders = new List(); foreach (var pair in boneTable) { @@ -170,7 +204,7 @@ public class SkeletonRagdoll : MonoBehaviour { localPos.x *= 1; joint.connectedAnchor = localPos; joint.axis = Vector3.forward; - joint.GetComponent().mass = joint.connectedBody.mass * 0.75f; + joint.GetComponent().mass = joint.connectedBody.mass * massFalloffFactor; JointLimits limits = new JointLimits(); limits.min = -rotationLimit; limits.max = rotationLimit; @@ -182,6 +216,7 @@ public class SkeletonRagdoll : MonoBehaviour { for (int x = 0; x < boneColliders.Count; x++) { for (int y = 0; y < boneColliders.Count; y++) { + if (x == y) continue; Physics.IgnoreCollision(boneColliders[x], boneColliders[y]); } } @@ -240,13 +275,13 @@ public class SkeletonRagdoll : MonoBehaviour { //physics if (colliders.Count == 0) { var ball = go.AddComponent(); - ball.radius = defaultThickness / 2f; + ball.radius = thickness / 2f; } } else { //physics if (colliders.Count == 0) { var box = go.AddComponent(); - box.size = new Vector3(length, defaultThickness, defaultThickness); + box.size = new Vector3(length, thickness, thickness); box.center = new Vector3((b.WorldFlipX ? -length : length) / 2, 0); } } @@ -254,7 +289,6 @@ public class SkeletonRagdoll : MonoBehaviour { var rb = go.AddComponent(); rb.constraints = RigidbodyConstraints.FreezePositionZ; foreach (Bone child in b.Children) { - RecursivelyCreateBoneProxies(child); } } @@ -281,7 +315,7 @@ public class SkeletonRagdoll : MonoBehaviour { continue; var collider = go.AddComponent(); - var bounds = SkeletonUtility.GetBoundingBoxBounds((BoundingBoxAttachment)a, defaultThickness); + var bounds = SkeletonUtility.GetBoundingBoxBounds((BoundingBoxAttachment)a, thickness); collider.center = bounds.center; collider.size = bounds.size; diff --git a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs index 88eba0990..690e10dd2 100644 --- a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs +++ b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs @@ -22,15 +22,17 @@ public class SkeletonRagdoll2D : MonoBehaviour { public bool applyOnStart; [Tooltip("Set RootRigidbody IsKinematic to true when Apply is called.")] public bool pinStartBone; - [Tooltip("Enable Collision between adjacent ragdoll elements (IE: Neck and Head)")] - public bool enableJointCollision; public float gravityScale = 1; [Tooltip("Warning! You will have to re-enable and tune mix values manually if attempting to remove the ragdoll system.")] public bool disableIK = true; [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 defaultThickness = 0.125f; + 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.")] public int colliderLayer = 0; [Range(0, 1)] @@ -110,7 +112,31 @@ public class SkeletonRagdoll2D : MonoBehaviour { UpdateWorld(null); skeleton.UpdateWorldTransform(); - //skeletonAnim.LateUpdate(); + } + + public Rigidbody2D[] GetRigidbodyArray () { + if (!isActive) + return new Rigidbody2D[0]; + + Rigidbody2D[] arr = new Rigidbody2D[boneTable.Count]; + int i = 0; + foreach (Transform t in boneTable.Values) { + arr[i] = t.GetComponent(); + i++; + } + + return arr; + } + + public Rigidbody2D GetRigidbody (string boneName) { + var bone = skeleton.FindBone(boneName); + if (bone == null) + return null; + + if (boneTable.ContainsKey(bone)) + return boneTable[bone].GetComponent(); + + return null; } public void Remove () { @@ -135,6 +161,7 @@ public class SkeletonRagdoll2D : MonoBehaviour { rootRigidbody = boneTable[ragdollRootBone].GetComponent(); rootRigidbody.isKinematic = pinStartBone; + rootRigidbody.mass = rootMass; List boneColliders = new List(); @@ -174,17 +201,18 @@ public class SkeletonRagdoll2D : MonoBehaviour { Vector3 localPos = parentTransform.InverseTransformPoint(t.position); localPos.x *= 1; joint.connectedAnchor = localPos; - joint.GetComponent().mass = joint.connectedBody.mass * 0.75f; + joint.GetComponent().mass = joint.connectedBody.mass * massFalloffFactor; JointAngleLimits2D limits = new JointAngleLimits2D(); limits.min = -rotationLimit; limits.max = rotationLimit; joint.limits = limits; - joint.useLimits = enableJointCollision; + joint.useLimits = true; } } 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]); } } @@ -245,13 +273,13 @@ public class SkeletonRagdoll2D : MonoBehaviour { //physics if (colliders.Count == 0) { var circle = go.AddComponent(); - circle.radius = defaultThickness / 2f; + circle.radius = thickness / 2f; } } else { //physics if (colliders.Count == 0) { var box = go.AddComponent(); - box.size = new Vector2(length, defaultThickness); + box.size = new Vector2(length, thickness); #if UNITY_5_0 box.offset = new Vector2((b.WorldFlipX ? -length : length) / 2, 0); #else @@ -330,8 +358,15 @@ public class SkeletonRagdoll2D : MonoBehaviour { flipY = parentBone.WorldFlipY; } else { - flipX = b.worldFlipX; - flipY = b.WorldFlipY; + parentBone = b.Parent; + parentTransform = ragdollRoot; + if (b.Parent != null) { + flipX = b.worldFlipX; + flipY = b.WorldFlipY; + } else { + flipX = b.Skeleton.FlipX; + flipY = b.Skeleton.FlipY; + } } flip = flipX ^ flipY; @@ -378,10 +413,10 @@ public class SkeletonRagdoll2D : MonoBehaviour { void OnDrawGizmosSelected () { if (isActive) { - Gizmos.DrawWireSphere(transform.position, defaultThickness * 1.2f); + Gizmos.DrawWireSphere(transform.position, thickness * 1.2f); Vector3 newTransformPos = rootRigidbody.position - rootOffset; Gizmos.DrawLine(transform.position, newTransformPos); - Gizmos.DrawWireSphere(newTransformPos, defaultThickness * 1.2f); + Gizmos.DrawWireSphere(newTransformPos, thickness * 1.2f); } }