Drago

Hi,

I have a sprite that moves in four directions. When the sprite turns to move forward the skin changes to a forward facing set of images. In Setup mode (within Spine) this looks odd. However, it is corrected in the first frame of the animation (Animation Mode).

In unity, when the forward direction button is pressed, the sprite changes skin correctly and the front walking animation starts. However, before it starts, the sprite returns momentarily to the way the bones appear in Setup mode (spine), it then quickly transitions to the front walking animation.

This is the code:
if (moveVelocity.y < 0)
{
if (skeletonAnimation.skeleton.data.FindSkin("Front") != null)
{

skeletonAnimation.skeleton.SetSkin("Front");
}
if (skeletonAnimation.state.GetCurrent(0).Animation.name!=("Walk_front"))
{

skeletonAnimation.state.SetAnimation(0, "Walk_front", true).TimeScale = 0.5f;
}


}
I have set the mix duration to 0 by default, but that has not resolved the problem.

Grateful for any help.

Thanks
Drago
  • Posts: 4

Pharan

In cases like this where it seems like the changes you apply (changing the skin, or setting an animation) is delayed, you have to consider where your code is running. If your Update runs after SkeletonAnimation.Update, animations may not be applied immediately. If your Update runs before SkeletonAnimation.Update, the animation may override your changes.

You may want to abstract this away into its own method. But to make sure that setting a skin or setting an animation immediately causes the visual appearance to be immediately reflected if your Update runs after SkeletonAnimation.Update, you need to apply the animation to the skeleton again, and update the attachment lookup again. It would look something like this:
skeletonAnimation.Skeleton.SetSkin("Front");
skeletonAnimation.Skeleton.SetSlotsToSetupMode(); // make sure attachments in the base pose are

skeletonAnimation.AnimationState.SetAnimation(0, "Walk_front", true);
skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); // make sure the attachments and bone poses in the current animation are used.
skeletonAnimation.Skeleton.UpdateWorldTransform(); // Make sure the skeleton pose is updated.
Note that this AnimationState.Apply(Skeleton) call can cause events to fire twice-- once in the regular update and then again in this Apply call. So if that's a concern, it's better to just let this piece of script run before SkeletonAnimation.Update. You can change the script execution order of your MonoBehaviour in your Unity Project\'s Script Execution Order window.
User avatar
Pharan
  • Posts: 5366

Drago

Thank you for your reply. Unfortunately, none of the suggestions appear to work.

By way of clarification. The function that deals with the animation is called from Update but is separate to it.

I implemented the suggested code and this did not make a difference. I also changed the execution order in Unity, which also did not change anything.

What seems to happen is that the bones gradually change position as the sprite goes from walking sideways to walking forward. However, it does not happen in reverse i.e. when the sprite changes from walking forward to walking sideways. On the other hand, it does happen if the change is from walking forward to side 'Idle'.

This is what the code that deals with the change from side to forward:
void PlayerMovementVertical()
{
if (moveVelocity.y < 0)
{
if (skeletonAnimation.skeleton.data.FindSkin("Front") != null)
{

skeletonAnimation.skeleton.SetSkin("Front");
skeletonAnimation.skeleton.SetBonesToSetupPose();
}
if (skeletonAnimation.state.GetCurrent(0).Animation.name!=("Walk_front"))
{
skeletonAnimation.state.Apply(skeletonAnimation.skeleton);
skeletonAnimation.state.SetAnimation(0, "Walk_front", true).TimeScale = 0.5f;
skeletonAnimation.skeleton.UpdateWorldTransform();
}
}
if (moveVelocity.y==0 && skeletonAnimation.skeleton.Skin.Name==("Front"))
{
if (skeletonAnimation.state.GetCurrent(0).Animation.name != ("Idle_front"))
{
skeletonAnimation.state.SetAnimation(0, "Idle_front", true).TimeScale=0.6f;
}

}
}
I cannot figure it out. Any further help will be much appreciated.

Thanks

---

Managed to get it to work. In addition, to the suggested code I set the Default Mix Duration to 0, this had not previously worked, but worked with the suggested code.

I need to look into this matter further so I fully understand the issue and how it has been resolved.

Grateful for your help.

---

Further note. It only works if I set the Default Mix Duration to 0. If I set the mix duration for the specific animations i.e. walk to Walk_front to 0, this will not work.
Drago
  • Posts: 4


Return to Unity