diff --git a/spine-unity/Assets/spine-unity/BoneFollower.cs b/spine-unity/Assets/spine-unity/BoneFollower.cs
index b1b740281..49ff44b27 100644
--- a/spine-unity/Assets/spine-unity/BoneFollower.cs
+++ b/spine-unity/Assets/spine-unity/BoneFollower.cs
@@ -138,7 +138,7 @@ namespace Spine.Unity {
// Recommended setup: Use local transform properties if Spine GameObject is the immediate parent
thisTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : thisTransform.localPosition.z);
if (followBoneRotation) {
- var halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f;
+ float halfRotation = Mathf.Atan2(bone.c, bone.a) * 0.5f;
if (followLocalScale && bone.scaleX < 0) // Negate rotation from negative scaleX. Don't use negative determinant. local scaleY doesn't factor into used rotation.
halfRotation += Mathf.PI * 0.5f;
diff --git a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs b/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
index 55d1f3ae8..ca11f4269 100644
--- a/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
+++ b/spine-unity/Assets/spine-unity/Editor/SpineAttributeDrawers.cs
@@ -79,10 +79,10 @@ namespace Spine.Unity.Editor {
var objectReferenceValue = dataField.objectReferenceValue;
if (objectReferenceValue is SkeletonDataAsset) {
skeletonDataAsset = (SkeletonDataAsset)objectReferenceValue;
- } else if (objectReferenceValue is ISkeletonComponent) {
- var skeletonComponent = (ISkeletonComponent)objectReferenceValue;
- if (skeletonComponent != null)
- skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
+ } else if (objectReferenceValue is IHasSkeletonDataAsset) {
+ var hasSkeletonDataAsset = (IHasSkeletonDataAsset)objectReferenceValue;
+ if (hasSkeletonDataAsset != null)
+ skeletonDataAsset = hasSkeletonDataAsset.SkeletonDataAsset;
} else if (objectReferenceValue != null) {
EditorGUI.LabelField(position, "ERROR:", "Invalid reference type");
return;
@@ -90,9 +90,9 @@ namespace Spine.Unity.Editor {
} else if (property.serializedObject.targetObject is Component) {
var component = (Component)property.serializedObject.targetObject;
- var skeletonComponent = component.GetComponentInChildren(typeof(ISkeletonComponent)) as ISkeletonComponent;
- if (skeletonComponent != null)
- skeletonDataAsset = skeletonComponent.SkeletonDataAsset;
+ var hasSkeletonDataAsset = component.GetComponentInChildren(typeof(IHasSkeletonDataAsset)) as IHasSkeletonDataAsset;
+ if (hasSkeletonDataAsset != null)
+ skeletonDataAsset = hasSkeletonDataAsset.SkeletonDataAsset;
}
if (skeletonDataAsset == null) {
diff --git a/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs b/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs
index 49889d3ea..d6b46271e 100644
--- a/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs
+++ b/spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs
@@ -220,9 +220,9 @@ namespace Spine.Unity.Editor {
public static bool TargetsUseSameData (SerializedObject so) {
if (so.isEditingMultipleObjects) {
int n = so.targetObjects.Length;
- var first = so.targetObjects[0] as ISkeletonComponent;
+ var first = so.targetObjects[0] as IHasSkeletonDataAsset;
for (int i = 1; i < n; i++) {
- var sr = so.targetObjects[i] as ISkeletonComponent;
+ var sr = so.targetObjects[i] as IHasSkeletonDataAsset;
if (sr != null && sr.SkeletonDataAsset != first.SkeletonDataAsset)
return false;
}
diff --git a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs b/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs
index f5e423adf..ebacb56fc 100644
--- a/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs
+++ b/spine-unity/Assets/spine-unity/ISkeletonAnimation.cs
@@ -42,7 +42,7 @@ namespace Spine.Unity {
}
/// Holds a reference to a SkeletonDataAsset.
- public interface ISkeletonDataAssetComponent {
+ public interface IHasSkeletonDataAsset {
/// Gets the SkeletonDataAsset of the Spine Component.
SkeletonDataAsset SkeletonDataAsset { get; }
}
diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader
index 653351778..262b90e5e 100644
--- a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader
+++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Fill.shader
@@ -9,7 +9,7 @@ Shader "Spine/Skeleton Fill" {
[NoScaleOffset]_MainTex ("MainTex", 2D) = "white" {}
}
SubShader {
- Tags { "IgnoreProjector"="True" "Queue"="Transparent" "RenderType"="Transparent" "PreviewType"="Plane" }
+ Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
Blend One OneMinusSrcAlpha
Cull Off
ZWrite Off
diff --git a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader b/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader
index 117ae495e..79bacb5cd 100644
--- a/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader
+++ b/spine-unity/Assets/spine-unity/Modules/Shaders/Spine-Skeleton-Tint.shader
@@ -13,7 +13,7 @@ Shader "Spine/Skeleton Tint" {
}
SubShader {
- Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
+ Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
Fog { Mode Off }
Cull Off
diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs
index 25e4d688c..3e04344b0 100644
--- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs
+++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs
@@ -35,7 +35,7 @@ using Spine;
namespace Spine.Unity {
[ExecuteInEditMode, RequireComponent(typeof(CanvasRenderer), typeof(RectTransform)), DisallowMultipleComponent]
[AddComponentMenu("Spine/SkeletonGraphic (Unity UI Canvas)")]
- public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation, ISkeletonDataAssetComponent {
+ public class SkeletonGraphic : MaskableGraphic, ISkeletonComponent, IAnimationStateComponent, ISkeletonAnimation, IHasSkeletonDataAsset {
#region Inspector
public SkeletonDataAsset skeletonDataAsset;
diff --git a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader b/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader
index 2741ba504..7b5c00d90 100644
--- a/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader
+++ b/spine-unity/Assets/spine-unity/Shaders/Spine-Skeleton.shader
@@ -5,7 +5,7 @@ Shader "Spine/Skeleton" {
}
SubShader {
- Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
+ Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane"}
Fog { Mode Off }
Cull Off
diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs
index 356cbd21f..17d851384 100644
--- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs
+++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs
@@ -38,7 +38,7 @@ namespace Spine.Unity {
/// Renders a skeleton.
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer)), DisallowMultipleComponent]
[HelpURL("http://esotericsoftware.com/spine-unity-documentation#Rendering")]
- public class SkeletonRenderer : MonoBehaviour, ISkeletonComponent, ISkeletonDataAssetComponent {
+ public class SkeletonRenderer : MonoBehaviour, ISkeletonComponent, IHasSkeletonDataAsset {
public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
public event SkeletonRendererDelegate OnRebuild;
diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs
index 0a6632e11..de58f122b 100644
--- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs
+++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs
@@ -28,8 +28,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
+//#define HINGECHAIN2D
// Contributed by: Mitch Thompson
+
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
@@ -277,6 +279,54 @@ namespace Spine.Unity.Editor {
EditorGUIUtility.PingObject(go);
}
+
+#if HINGECHAIN2D
+ bool CanCreateHingeChain () {
+ if (utilityBone == null) return false;
+ if (utilityBone.GetComponent() != null) return false;
+ if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0) return false;
+ var rigidbodies = utilityBone.GetComponentsInChildren();
+ return rigidbodies.Length <= 0;
+ }
+
+ void CreateHingeChain () {
+ var utilBoneArr = utilityBone.GetComponentsInChildren();
+
+ foreach (var utilBone in utilBoneArr) {
+ if (utilBone.GetComponent() == null) {
+ if (utilBone.bone.Data.Length == 0) {
+ var sphere = utilBone.gameObject.AddComponent();
+ sphere.radius = 0.1f;
+ } else {
+ float length = utilBone.bone.Data.Length;
+ var box = utilBone.gameObject.AddComponent();
+ box.size = new Vector3(length, length / 3f, 0.2f);
+ box.offset = new Vector3(length / 2f, 0, 0);
+ }
+ }
+
+ utilBone.gameObject.AddComponent();
+ }
+
+ utilityBone.GetComponent().isKinematic = true;
+
+ foreach (var utilBone in utilBoneArr) {
+ if (utilBone == utilityBone)
+ continue;
+
+ utilBone.mode = SkeletonUtilityBone.Mode.Override;
+
+ var joint = utilBone.gameObject.AddComponent();
+ joint.connectedBody = utilBone.transform.parent.GetComponent();
+ joint.useLimits = true;
+ joint.limits = new JointAngleLimits2D {
+ min = -20,
+ max = 20
+ };
+ utilBone.GetComponent().mass = utilBone.transform.parent.GetComponent().mass * 0.75f;
+ }
+ }
+#else
bool CanCreateHingeChain () {
if (utilityBone == null)
return false;
@@ -285,7 +335,7 @@ namespace Spine.Unity.Editor {
if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0)
return false;
- Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren();
+ var rigidbodies = utilityBone.GetComponentsInChildren();
return rigidbodies.Length <= 0;
}
@@ -332,6 +382,7 @@ namespace Spine.Unity.Editor {
utilBone.gameObject.AddComponent();
}
+#endif
}
}
diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs
index 9765e4b66..8280a05d3 100644
--- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs
+++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs
@@ -267,27 +267,27 @@ namespace Spine.Unity {
for (int i = 0, n = utilityBones.Count; i < n; i++)
utilityBones[i].transformLerpComplete = false;
- UpdateAllBones();
+ UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Local);
}
void UpdateWorld (ISkeletonAnimation anim) {
- UpdateAllBones();
+ UpdateAllBones(SkeletonUtilityBone.UpdatePhase.World);
for (int i = 0, n = utilityConstraints.Count; i < n; i++)
utilityConstraints[i].DoUpdate();
}
void UpdateComplete (ISkeletonAnimation anim) {
- UpdateAllBones();
+ UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Complete);
}
- void UpdateAllBones () {
+ void UpdateAllBones (SkeletonUtilityBone.UpdatePhase phase) {
if (boneRoot == null)
CollectBones();
var utilityBones = this.utilityBones;
if (utilityBones == null) return;
for (int i = 0, n = utilityBones.Count; i < n; i++)
- utilityBones[i].DoUpdate();
+ utilityBones[i].DoUpdate(phase);
}
public Transform GetBoneRoot () {
diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs
index f4670d8f1..1cec0264b 100644
--- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs
+++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs
@@ -43,6 +43,12 @@ namespace Spine.Unity {
Override
}
+ public enum UpdatePhase {
+ Local,
+ World,
+ Complete
+ }
+
#region Inspector
/// If a bone isn't set, boneName is used to find the bone.
public string boneName;
@@ -71,7 +77,7 @@ namespace Spine.Unity {
skeletonTransform = skeletonUtility.transform;
skeletonUtility.OnReset -= HandleOnReset;
skeletonUtility.OnReset += HandleOnReset;
- DoUpdate();
+ DoUpdate(UpdatePhase.Local);
}
void OnEnable () {
@@ -95,7 +101,7 @@ namespace Spine.Unity {
}
}
- public void DoUpdate () {
+ public void DoUpdate (UpdatePhase phase) {
if (!valid) {
Reset();
return;
@@ -112,46 +118,72 @@ namespace Spine.Unity {
}
}
+ var thisTransform = cachedTransform;
float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
if (mode == Mode.Follow) {
- if (!bone.appliedValid)
- bone.UpdateAppliedTransform();
+ switch (phase) {
+ case UpdatePhase.Local:
+ if (position)
+ thisTransform.localPosition = new Vector3(bone.x, bone.y, 0);
- if (position)
- cachedTransform.localPosition = new Vector3(bone.ax, bone.ay, 0);
+ if (rotation) {
+ if (bone.data.transformMode.InheritsRotation()) {
+ thisTransform.localRotation = Quaternion.Euler(0, 0, bone.rotation);
+ } else {
+ Vector3 euler = skeletonTransform.rotation.eulerAngles;
+ thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
+ }
+ }
+
+ if (scale) {
+ thisTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f);
+ incompatibleTransformMode = BoneTransformModeIncompatible(bone);
+ }
+ break;
+ case UpdatePhase.World:
+ case UpdatePhase.Complete:
+ // Use Applied transform values (ax, ay, AppliedRotation, ascale) if world values were modified by constraints.
+ if (!bone.appliedValid) {
+ bone.UpdateAppliedTransform();
+ if (position)
+ thisTransform.localPosition = new Vector3(bone.ax, bone.ay, 0);
+
+ if (rotation) {
+ if (bone.data.transformMode.InheritsRotation()) {
+ thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
+ } else {
+ Vector3 euler = skeletonTransform.rotation.eulerAngles;
+ thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
+ }
+ }
+
+ if (scale) {
+ thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
+ incompatibleTransformMode = BoneTransformModeIncompatible(bone);
+ }
+ }
+ break;
+ }
- if (rotation) {
- if (bone.data.transformMode.InheritsRotation()) {
- cachedTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
- } else {
- Vector3 euler = skeletonTransform.rotation.eulerAngles;
- cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
- }
- }
-
- if (scale) {
- cachedTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
- incompatibleTransformMode = BoneTransformModeIncompatible(bone);
- }
} else if (mode == Mode.Override) {
if (transformLerpComplete)
return;
if (parentReference == null) {
if (position) {
- Vector3 clp = cachedTransform.localPosition;
+ Vector3 clp = thisTransform.localPosition;
bone.x = Mathf.Lerp(bone.x, clp.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, clp.y, overrideAlpha);
}
if (rotation) {
- float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha);
+ float angle = Mathf.LerpAngle(bone.Rotation, thisTransform.localRotation.eulerAngles.z, overrideAlpha);
bone.Rotation = angle;
bone.AppliedRotation = angle;
}
if (scale) {
- Vector3 cls = cachedTransform.localScale;
+ Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha);
}
@@ -161,19 +193,19 @@ namespace Spine.Unity {
return;
if (position) {
- Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position);
+ Vector3 pos = parentReference.InverseTransformPoint(thisTransform.position);
bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
}
if (rotation) {
- float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha);
+ float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(thisTransform.up)).eulerAngles.z, overrideAlpha);
bone.Rotation = angle;
bone.AppliedRotation = angle;
}
if (scale) {
- Vector3 cls = cachedTransform.localScale;
+ Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha);
}