[unity] Fixed initial animation not being mixed out in some circumstances due to PoseSkeleton call. Removed PoseSkeleton and PoseWithAnimation extension methods to prevent related issues on user side. Fixed incorrect random Nth frame preview in Scene view for SkeletonAnimation and SkeletonGraphic. Closes #1340.

This commit is contained in:
Harald Csaszar 2019-04-25 18:41:56 +02:00
parent e09ea0b212
commit 89e759a8f5
7 changed files with 49 additions and 83 deletions

View File

@ -56,7 +56,7 @@ namespace Spine.Unity.Examples {
if (skeletonRenderer == null) return;
var skeleton = skeletonRenderer.skeleton; if (skeleton == null) return;
fillAnimation.Animation.PoseSkeleton(skeleton, percent);
fillAnimation.Animation.Apply(skeleton, 0, percent, false, null, 1f, MixBlend.Setup, MixDirection.In);
skeleton.Update(Time.deltaTime);
skeleton.UpdateWorldTransform();
}

View File

@ -55,38 +55,26 @@ namespace Spine.Unity.Editor {
if (!TargetIsValid) return;
bool sameData = SpineInspectorUtility.TargetsUseSameData(serializedObject);
if (multi) {
foreach (var o in targets)
TrySetAnimation(o as SkeletonAnimation, multi);
EditorGUILayout.Space();
if (!sameData) {
EditorGUILayout.DelayedTextField(animationName);
} else {
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(animationName);
wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update.
}
EditorGUILayout.PropertyField(loop);
EditorGUILayout.PropertyField(timeScale);
foreach (var o in targets) {
var component = o as SkeletonAnimation;
component.timeScale = Mathf.Max(component.timeScale, 0);
}
} else {
TrySetAnimation(target as SkeletonAnimation, multi);
foreach (var o in targets)
TrySetAnimation(o as SkeletonAnimation, multi);
wasAnimationNameChanged = false;
EditorGUILayout.Space();
EditorGUILayout.Space();
if (!sameData) {
EditorGUILayout.DelayedTextField(animationName);
} else {
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(animationName);
wasAnimationNameChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update.
EditorGUILayout.PropertyField(loop, LoopLabel);
EditorGUILayout.PropertyField(timeScale, TimeScaleLabel);
var component = (SkeletonAnimation)target;
component.timeScale = Mathf.Max(component.timeScale, 0);
EditorGUILayout.Space();
}
EditorGUILayout.PropertyField(loop, LoopLabel);
EditorGUILayout.PropertyField(timeScale, TimeScaleLabel);
foreach (var o in targets) {
var component = o as SkeletonAnimation;
component.timeScale = Mathf.Max(component.timeScale, 0);
}
EditorGUILayout.Space();
if (!isInspectingPrefab) {
if (requireRepaint) {
SceneView.RepaintAll();
@ -113,7 +101,9 @@ namespace Spine.Unity.Editor {
Spine.Animation animationToUse = skeleton.Data.FindAnimation(animationName.stringValue);
if (!Application.isPlaying) {
if (animationToUse != null) animationToUse.PoseSkeleton(skeleton, 0f);
if (animationToUse != null) {
skeletonAnimation.AnimationState.SetAnimation(0, animationToUse, loop.boolValue);
}
skeleton.UpdateWorldTransform();
skeletonAnimation.LateUpdate();
requireRepaint = true;
@ -123,12 +113,10 @@ namespace Spine.Unity.Editor {
else
state.ClearTrack(0);
}
wasAnimationNameChanged = false;
}
// Reflect animationName serialized property in the inspector even if SetAnimation API was used.
if (!multi && Application.isPlaying) {
if (Application.isPlaying) {
TrackEntry current = skeletonAnimation.AnimationState.GetCurrent(0);
if (current != null) {
if (skeletonAnimation.AnimationName != animationName.stringValue)

View File

@ -831,7 +831,7 @@ namespace Spine.Unity.Editor {
Skeleton skeleton = bone.Skeleton;
bool inheritRotation = bone.Data.TransformMode.InheritsRotation();
animation.PoseSkeleton(skeleton, 0);
animation.Apply(skeleton, 0, 0, false, null, 1f, MixBlend.Setup, MixDirection.In);
skeleton.UpdateWorldTransform();
float duration = animation.Duration;
@ -859,7 +859,7 @@ namespace Spine.Unity.Editor {
if (i == steps)
currentTime = duration;
animation.PoseSkeleton(skeleton, currentTime, true);
animation.Apply(skeleton, 0, currentTime, true, null, 1f, MixBlend.Setup, MixDirection.In);
skeleton.UpdateWorldTransform();
int pIndex = listIndex - 1;

View File

@ -158,24 +158,23 @@ namespace Spine.Unity {
if (!string.IsNullOrEmpty(_animationName)) {
var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(_animationName);
if (animationObject != null) {
animationObject.PoseSkeleton(skeleton, 0f);
skeleton.UpdateWorldTransform();
state.SetAnimation(0, animationObject, loop);
#if UNITY_EDITOR
if (Application.isPlaying) {
#endif
// In Unity Editor edit mode, make this block not run.
state.SetAnimation(0, animationObject, loop);
#if UNITY_EDITOR
}
if (!Application.isPlaying)
Update(0f);
#endif
}
}
}
void Update () {
#if UNITY_EDITOR
if (!Application.isPlaying) {
Update(0f);
return;
}
#endif
Update(Time.deltaTime);
}

View File

@ -92,12 +92,14 @@ namespace Spine.Unity {
if (!Application.isPlaying) {
skeleton.scaleX = this.initialFlipX ? -1 : 1;
skeleton.scaleY = this.initialFlipY ? -1 : 1;
state.ClearTrack(0);
skeleton.SetToSetupPose();
if (!string.IsNullOrEmpty(startingAnimation))
skeleton.PoseWithAnimation(startingAnimation, 0f, false);
if (!string.IsNullOrEmpty(startingAnimation)) {
state.SetAnimation(0, startingAnimation, startingLoop);
Update(0f);
}
}
}
} else {
// Under some circumstances (e.g. sometimes on the first import) OnValidate is called
@ -181,6 +183,13 @@ namespace Spine.Unity {
}
public virtual void Update () {
#if UNITY_EDITOR
if (!Application.isPlaying) {
Update(0f);
return;
}
#endif
if (freeze) return;
Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime);
}
@ -273,22 +282,11 @@ namespace Spine.Unity {
if (!string.IsNullOrEmpty(startingAnimation)) {
var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation);
if (animationObject != null) {
animationObject.PoseSkeleton(skeleton, 0f);
skeleton.UpdateWorldTransform();
state.SetAnimation(0, animationObject, startingLoop);
#if UNITY_EDITOR
if (Application.isPlaying) {
if (!Application.isPlaying)
Update(0f);
#endif
// Make this block not run in Unity Editor edit mode.
state.SetAnimation(0, animationObject, startingLoop);
#if UNITY_EDITOR
}
#endif
}
else {
startingAnimation = string.Empty;
}
}
}

View File

@ -181,7 +181,7 @@ namespace Spine.Unity.Playables {
} else {
skeleton.SetToSetupPose();
if (toAnimation != null)
toAnimation.PoseSkeleton(skeleton, toClipTime, clipData.loop);
toAnimation.Apply(skeleton, 0, toClipTime, clipData.loop, null, 1f, MixBlend.Setup, MixDirection.In);
}
}

View File

@ -601,25 +601,6 @@ namespace Spine {
}
}
/// <summary>
/// Shortcut for posing a skeleton at a specific time. Time is in seconds. (frameNumber / 30f) will give you seconds.
/// If you need to do this often, you should get the Animation object yourself using skeleton.data.FindAnimation. and call Apply on that.</summary>
/// <param name = "skeleton">The skeleton to pose.</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 = "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 = false) {
// Fail loud when skeleton.data is null.
Spine.Animation animation = skeleton.data.FindAnimation(animationName);
if (animation == null) return;
animation.Apply(skeleton, 0, time, loop, null, 1f, MixBlend.Setup, MixDirection.In);
}
/// <summary>Pose a skeleton according to a given time in an animation. This is the simplified version of Animation.Apply(skeleton).</summary>
public static void PoseSkeleton (this Animation animation, Skeleton skeleton, float time, bool loop = false) {
animation.Apply(skeleton, 0, time, loop, null, 1f, MixBlend.Setup, MixDirection.In);
}
/// <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) {
animation.Apply(skeleton, 0, 0, false, null, 0, MixBlend.Setup, MixDirection.Out);