[unity] Update calls to Timeline/Animation.Apply. And other cleanup.

This commit is contained in:
pharan 2017-06-13 08:51:53 +08:00
parent 44a44aa6c6
commit 7481a05931
7 changed files with 186 additions and 167 deletions

View File

@ -65,7 +65,7 @@ namespace Spine.Unity.Examples {
if (fillAnimation == null) return; if (fillAnimation == null) return;
} }
fillAnimation.Apply(skeleton, 0, percent, false, null, 1f, true, false); fillAnimation.Apply(skeleton, 0, percent, false, null, 1f, MixPose.Setup, MixDirection.In);
skeleton.Update(Time.deltaTime); skeleton.Update(Time.deltaTime);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();

View File

@ -115,8 +115,8 @@ namespace Spine.Unity.Editor {
Spine.Animation animationToUse = skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue); Spine.Animation animationToUse = skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue);
if (!Application.isPlaying) { if (!Application.isPlaying) {
if (animationToUse != null) animationToUse.Apply(skeletonAnimation.skeleton, 0f, 0f, false, null, 1f, true, false); if (animationToUse != null) animationToUse.PoseSkeleton(skeletonAnimation.Skeleton, 0f);
skeletonAnimation.Update(); skeletonAnimation.Update(0);
skeletonAnimation.LateUpdate(); skeletonAnimation.LateUpdate();
requireRepaint = true; requireRepaint = true;
} else { } else {

View File

@ -931,7 +931,7 @@ namespace Spine.Unity.Editor {
Skeleton skeleton = bone.Skeleton; Skeleton skeleton = bone.Skeleton;
bool inheritRotation = bone.Data.TransformMode.InheritsRotation(); bool inheritRotation = bone.Data.TransformMode.InheritsRotation();
animation.Apply(skeleton, 0, 0, true, null, 1f, true, false); animation.PoseSkeleton(skeleton, 0);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
float duration = animation.Duration; float duration = animation.Duration;
@ -952,7 +952,6 @@ namespace Spine.Unity.Editor {
int steps = Mathf.CeilToInt(duration / bakeIncrement); int steps = Mathf.CeilToInt(duration / bakeIncrement);
float currentTime = 0; float currentTime = 0;
float lastTime = 0;
float angle = rotation; float angle = rotation;
for (int i = 1; i <= steps; i++) { for (int i = 1; i <= steps; i++) {
@ -960,7 +959,7 @@ namespace Spine.Unity.Editor {
if (i == steps) if (i == steps)
currentTime = duration; currentTime = duration;
animation.Apply(skeleton, lastTime, currentTime, true, null, 1f, true, false); animation.PoseSkeleton(skeleton, currentTime, true);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
int pIndex = listIndex - 1; int pIndex = listIndex - 1;
@ -969,11 +968,7 @@ namespace Spine.Unity.Editor {
pk = keys[pIndex]; pk = keys[pIndex];
if (inheritRotation) rotation = inheritRotation ? bone.AppliedRotation : GetUninheritedRotation(bone);
rotation = bone.AppliedRotation;
else {
rotation = GetUninheritedRotation(bone);
}
angle += Mathf.DeltaAngle(angle, rotation); angle += Mathf.DeltaAngle(angle, rotation);
@ -988,7 +983,6 @@ namespace Spine.Unity.Editor {
keys[pIndex] = pk; keys[pIndex] = pk;
listIndex++; listIndex++;
lastTime = currentTime;
} }
curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray()));
@ -1058,7 +1052,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1085,7 +1079,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1104,7 +1098,7 @@ namespace Spine.Unity.Editor {
if (i == steps) if (i == steps)
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
px = xKeys[listIndex - 1]; px = xKeys[listIndex - 1];
py = yKeys[listIndex - 1]; py = yKeys[listIndex - 1];
@ -1201,7 +1195,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1228,7 +1222,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1246,7 +1240,7 @@ namespace Spine.Unity.Editor {
if (i == steps) if (i == steps)
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
px = xKeys[listIndex - 1]; px = xKeys[listIndex - 1];
py = yKeys[listIndex - 1]; py = yKeys[listIndex - 1];
@ -1330,7 +1324,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1355,7 +1349,7 @@ namespace Spine.Unity.Editor {
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
lastTime = time; lastTime = time;
listIndex++; listIndex++;
@ -1365,7 +1359,7 @@ namespace Spine.Unity.Editor {
float time = frames[f]; float time = frames[f];
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
rotation = frames[f + 1] + boneData.Rotation; rotation = frames[f + 1] + boneData.Rotation;
@ -1379,7 +1373,7 @@ namespace Spine.Unity.Editor {
if (i == steps) if (i == steps)
currentTime = time; currentTime = time;
timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
pk = keys[listIndex - 1]; pk = keys[listIndex - 1];
@ -1407,7 +1401,7 @@ namespace Spine.Unity.Editor {
curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray()));
string path = GetPath(boneData); string path = GetPath(boneData);
string propertyName = "localEulerAnglesBaked"; const string propertyName = "localEulerAnglesBaked";
EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x");
AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve());

View File

@ -242,7 +242,7 @@ namespace Spine.Unity {
// Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above.
var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation); var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation);
if (animationObject != null) if (animationObject != null)
animationObject.Apply(skeleton, 0f, 0f, false, null, 1f, true, false); animationObject.PoseSkeleton(skeleton, 0);
} }
Update(0); Update(0);
} }

View File

@ -150,7 +150,7 @@ namespace Spine.Unity {
// Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above.
var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(_animationName); var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(_animationName);
if (animationObject != null) if (animationObject != null)
animationObject.Apply(skeleton, 0f, 0f, false, null, 1f, true, false); animationObject.PoseSkeleton(skeleton, 0f);
} }
Update(0); Update(0);
} }
@ -162,10 +162,11 @@ namespace Spine.Unity {
#endif #endif
} }
public void Update () { void Update () {
Update(Time.deltaTime); Update(Time.deltaTime);
} }
/// <summary>Progresses the AnimationState according to the given deltaTime, and applies it to the Skeleton. Use Time.deltaTime to update manually. Use deltaTime 0 to update without progressing the time.</summary>
public void Update (float deltaTime) { public void Update (float deltaTime) {
if (!valid) if (!valid)
return; return;

View File

@ -40,9 +40,6 @@ namespace Spine.Unity {
public enum MixMode { AlwaysMix, MixNext, SpineStyle } public enum MixMode { AlwaysMix, MixNext, SpineStyle }
public MixMode[] layerMixModes = new MixMode[0]; public MixMode[] layerMixModes = new MixMode[0];
public bool autoReset = true;
List<Animation> previousAnimations = new List<Animation>();
#region Bone Callbacks (ISkeletonAnimation) #region Bone Callbacks (ISkeletonAnimation)
protected event UpdateBonesDelegate _UpdateLocal; protected event UpdateBonesDelegate _UpdateLocal;
protected event UpdateBonesDelegate _UpdateWorld; protected event UpdateBonesDelegate _UpdateWorld;
@ -66,25 +63,24 @@ namespace Spine.Unity {
public event UpdateBonesDelegate UpdateComplete { add { _UpdateComplete += value; } remove { _UpdateComplete -= value; } } public event UpdateBonesDelegate UpdateComplete { add { _UpdateComplete += value; } remove { _UpdateComplete -= value; } }
#endregion #endregion
public class SpineMecanimTranslator {
readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>(); readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>();
readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>(); readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>();
Animator animator; Animator animator;
public override void Initialize (bool overwrite) { List<Animation> previousAnimations = new List<Animation>();
if (valid && !overwrite) return; public bool autoReset = true;
base.Initialize(overwrite);
if (!valid) return;
public void Initialize (Animator animator, SkeletonDataAsset skeletonDataAsset) {
this.animator = animator;
animationTable.Clear(); animationTable.Clear();
clipNameHashCodeTable.Clear(); clipNameHashCodeTable.Clear();
animator = GetComponent<Animator>();
var data = skeletonDataAsset.GetSkeletonData(true); var data = skeletonDataAsset.GetSkeletonData(true);
foreach (var a in data.Animations) foreach (var a in data.Animations)
animationTable.Add(a.Name.GetHashCode(), a); animationTable.Add(a.Name.GetHashCode(), a);
} }
public void Update () { public void Apply (Skeleton skeleton, ref MixMode[] layerMixModes) {
if (!valid) return;
if (layerMixModes.Length < animator.layerCount) if (layerMixModes.Length < animator.layerCount)
System.Array.Resize<MixMode>(ref layerMixModes, animator.layerCount); System.Array.Resize<MixMode>(ref layerMixModes, animator.layerCount);
@ -142,12 +138,12 @@ namespace Spine.Unity {
// Always use Mix instead of Applying the first non-zero weighted clip. // Always use Mix instead of Applying the first non-zero weighted clip.
for (int c = 0; c < clipInfo.Length; c++) { for (int c = 0; c < clipInfo.Length; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
} }
if (hasNext) { if (hasNext) {
for (int c = 0; c < nextClipInfo.Length; c++) { for (int c = 0; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
} }
} }
} else { // case MixNext || SpineStyle } else { // case MixNext || SpineStyle
@ -155,13 +151,13 @@ namespace Spine.Unity {
int c = 0; int c = 0;
for (; c < clipInfo.Length; c++) { for (; c < clipInfo.Length; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, 1f, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, 1f, MixPose.Current, MixDirection.In);
break; break;
} }
// Mix the rest // Mix the rest
for (; c < clipInfo.Length; c++) { for (; c < clipInfo.Length; c++) {
var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
} }
c = 0; c = 0;
@ -170,34 +166,18 @@ namespace Spine.Unity {
if (mode == MixMode.SpineStyle) { if (mode == MixMode.SpineStyle) {
for (; c < nextClipInfo.Length; c++) { for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, MixPose.Current, MixDirection.In);
break; break;
} }
} }
// Mix the rest // Mix the rest
for (; c < nextClipInfo.Length; c++) { for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, false, false); animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
} }
} }
} }
} }
// UpdateWorldTransform and Bone Callbacks
{
if (_UpdateLocal != null)
_UpdateLocal(this);
skeleton.UpdateWorldTransform();
if (_UpdateWorld != null) {
_UpdateWorld(this);
skeleton.UpdateWorldTransform();
}
if (_UpdateComplete != null)
_UpdateComplete(this);
}
} }
static float AnimationTime (float normalizedTime, float clipLength, bool loop, bool reversed) { static float AnimationTime (float normalizedTime, float clipLength, bool loop, bool reversed) {
@ -225,4 +205,38 @@ namespace Spine.Unity {
return clipNameHashCode; return clipNameHashCode;
} }
} }
public SpineMecanimTranslator translator;
public override void Initialize (bool overwrite) {
if (valid && !overwrite) return;
base.Initialize(overwrite);
if (!valid) return;
translator = new SpineMecanimTranslator();
translator.Initialize(GetComponent<Animator>(), this.skeletonDataAsset);
}
public void Update () {
if (!valid) return;
translator.Apply(skeleton, ref layerMixModes);
// UpdateWorldTransform and Bone Callbacks
{
if (_UpdateLocal != null)
_UpdateLocal(this);
skeleton.UpdateWorldTransform();
if (_UpdateWorld != null) {
_UpdateWorld(this);
skeleton.UpdateWorldTransform();
}
if (_UpdateComplete != null)
_UpdateComplete(this);
}
}
}
} }

View File

@ -283,11 +283,6 @@ namespace Spine {
#endregion #endregion
#region Posing #region Posing
[System.Obsolete("Old Animation.Apply method signature. Please use the 8 parameter signature. See summary to learn about the extra arguments.")]
public static void Apply (this Spine.Animation animation, Skeleton skeleton, float lastTime, float time, bool loop, ExposedList<Event> events) {
animation.Apply(skeleton, lastTime, time, loop, events, 1f, false, false);
}
internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) { internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) {
int tt = propertyID >> 24; int tt = propertyID >> 24;
var timelineType = (TimelineType)tt; var timelineType = (TimelineType)tt;
@ -326,6 +321,9 @@ namespace Spine {
case TimelineType.Color: case TimelineType.Color:
skeleton.slots.Items[i].SetColorToSetupPose(); skeleton.slots.Items[i].SetColorToSetupPose();
break; break;
case TimelineType.TwoColor:
skeleton.slots.Items[i].SetColorToSetupPose();
break;
case TimelineType.Deform: case TimelineType.Deform:
skeleton.slots.Items[i].attachmentVertices.Clear(); skeleton.slots.Items[i].attachmentVertices.Clear();
break; break;
@ -341,6 +339,8 @@ namespace Spine {
ikc.mix = ikc.data.mix; ikc.mix = ikc.data.mix;
ikc.bendDirection = ikc.data.bendDirection; ikc.bendDirection = ikc.data.bendDirection;
break; break;
// TransformConstraint
case TimelineType.TransformConstraint: case TimelineType.TransformConstraint:
var tc = skeleton.transformConstraints.Items[i]; var tc = skeleton.transformConstraints.Items[i];
var tcData = tc.data; var tcData = tc.data;
@ -384,6 +384,9 @@ namespace Spine {
slot.g = slot.data.g; slot.g = slot.data.g;
slot.b = slot.data.b; slot.b = slot.data.b;
slot.a = slot.data.a; slot.a = slot.data.a;
slot.r2 = slot.data.r2;
slot.g2 = slot.data.g2;
slot.b2 = slot.data.b2;
} }
/// <summary>Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster.</summary> /// <summary>Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster.</summary>
@ -411,17 +414,24 @@ namespace Spine {
/// <param name="animationName">The name of the animation to use.</param> /// <param name="animationName">The name of the animation to use.</param>
/// <param name = "time">The time of the pose within the animation.</param> /// <param name = "time">The time of the pose within the animation.</param>
/// <param name = "loop">Wraps the time around if it is longer than the duration of the animation.</param> /// <param name = "loop">Wraps the time around if it is longer than the duration of the animation.</param>
public static void PoseWithAnimation (this Skeleton skeleton, string animationName, float time, bool loop) { public static void PoseWithAnimation (this Skeleton skeleton, string animationName, float time, bool loop = false) {
// Fail loud when skeleton.data is null. // Fail loud when skeleton.data is null.
Spine.Animation animation = skeleton.data.FindAnimation(animationName); Spine.Animation animation = skeleton.data.FindAnimation(animationName);
if (animation == null) return; if (animation == null) return;
animation.Apply(skeleton, 0, time, loop, null, 1f, false, false); animation.Apply(skeleton, 0, time, loop, null, 1f, MixPose.Setup, MixDirection.In);
}
/// <summary>Pose a skeleton according to a given time in an animation.</summary>
public static void PoseSkeleton (this Animation animation, Skeleton skeleton, float time, bool loop = false) {
animation.Apply(skeleton, 0, time, loop, null, 1f, MixPose.Setup, MixDirection.In);
} }
/// <summary>Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items.</summary> /// <summary>Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items.</summary>
public static void SetKeyedItemsToSetupPose (this Animation animation, Skeleton skeleton) { public static void SetKeyedItemsToSetupPose (this Animation animation, Skeleton skeleton) {
animation.Apply(skeleton, 0, 0, false, null, 0, true, true); animation.Apply(skeleton, 0, 0, false, null, 0, MixPose.Setup, MixDirection.Out);
} }
#endregion #endregion
#region Skins #region Skins