mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-10 17:18:44 +08:00
Merge branch '3.6' of https://github.com/esotericsoftware/spine-runtimes into 3.6
This commit is contained in:
commit
39c63887c0
@ -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;
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Spine.Unity {
|
||||
}
|
||||
|
||||
/// <summary>Holds a reference to a SkeletonDataAsset.</summary>
|
||||
public interface ISkeletonDataAssetComponent {
|
||||
public interface IHasSkeletonDataAsset {
|
||||
/// <summary>Gets the SkeletonDataAsset of the Spine Component.</summary>
|
||||
SkeletonDataAsset SkeletonDataAsset { get; }
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine.Unity {
|
||||
/// <summary>Renders a skeleton.</summary>
|
||||
[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;
|
||||
|
||||
@ -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<Rigidbody2D>() != null) return false;
|
||||
if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0) return false;
|
||||
var rigidbodies = utilityBone.GetComponentsInChildren<Rigidbody2D>();
|
||||
return rigidbodies.Length <= 0;
|
||||
}
|
||||
|
||||
void CreateHingeChain () {
|
||||
var utilBoneArr = utilityBone.GetComponentsInChildren<SkeletonUtilityBone>();
|
||||
|
||||
foreach (var utilBone in utilBoneArr) {
|
||||
if (utilBone.GetComponent<Collider2D>() == null) {
|
||||
if (utilBone.bone.Data.Length == 0) {
|
||||
var sphere = utilBone.gameObject.AddComponent<CircleCollider2D>();
|
||||
sphere.radius = 0.1f;
|
||||
} else {
|
||||
float length = utilBone.bone.Data.Length;
|
||||
var box = utilBone.gameObject.AddComponent<BoxCollider2D>();
|
||||
box.size = new Vector3(length, length / 3f, 0.2f);
|
||||
box.offset = new Vector3(length / 2f, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
utilBone.gameObject.AddComponent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
utilityBone.GetComponent<Rigidbody2D>().isKinematic = true;
|
||||
|
||||
foreach (var utilBone in utilBoneArr) {
|
||||
if (utilBone == utilityBone)
|
||||
continue;
|
||||
|
||||
utilBone.mode = SkeletonUtilityBone.Mode.Override;
|
||||
|
||||
var joint = utilBone.gameObject.AddComponent<HingeJoint2D>();
|
||||
joint.connectedBody = utilBone.transform.parent.GetComponent<Rigidbody2D>();
|
||||
joint.useLimits = true;
|
||||
joint.limits = new JointAngleLimits2D {
|
||||
min = -20,
|
||||
max = 20
|
||||
};
|
||||
utilBone.GetComponent<Rigidbody2D>().mass = utilBone.transform.parent.GetComponent<Rigidbody2D>().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<Rigidbody>();
|
||||
var rigidbodies = utilityBone.GetComponentsInChildren<Rigidbody>();
|
||||
|
||||
return rigidbodies.Length <= 0;
|
||||
}
|
||||
@ -332,6 +382,7 @@ namespace Spine.Unity.Editor {
|
||||
|
||||
utilBone.gameObject.AddComponent<Rigidbody>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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 () {
|
||||
|
||||
@ -43,6 +43,12 @@ namespace Spine.Unity {
|
||||
Override
|
||||
}
|
||||
|
||||
public enum UpdatePhase {
|
||||
Local,
|
||||
World,
|
||||
Complete
|
||||
}
|
||||
|
||||
#region Inspector
|
||||
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user