- 수정됨
Switch skeletons quickly
I am making an 8-directional movement, using 5 directions, where Left mirrors Right (and UL/DL mirror UR/DR).
Each of the base 5 directions is a separate Spine project, each it has its own animations e.g. "idle" and "walk".
And they are combined by a parent GameObject:
The parent has an animator, where it has a state for each direction:
Each one is associated with a script to iterate over children and enable/disable the MeshRenderer
s accordingly (far below).
With Spine, during the switch from right to left (using a tool called AdventureCreator
), the animation incorrectness is detected by the eyes, even with simple skeletons with one image and no animation, e.g. which clicking on left, the right direction is shown for very short period of time.
4 directions:
8 directions:
I tested the same scenario with simple images, with the same Controller and same script (using SpriteRenderer
instead), and the movement is smooth:
I was able to fix it with Spine, by duplicating the right directions, and not changing the scaleX
programatically, but I feel this is more of a workaround, and it means the character will always move with 8 skeletons instead of 5.
My questions are:
- Is this the correct way to handle shifting between skeletons?
- How can I use only 5 skeletons and flip the other 3 programatically with smooth movements?
Thanks a lot,
public class SpineAnimationScript : StateMachineBehaviour
{
public string animationName;
public string direction;
public override void OnStateEnter(Animator animator, AnimatorStateInfo
stateInfo, int layerIndex)
{
foreach (Transform t in animator.gameObject.transform)
{
var go = t.gameObject;
var reversed = direction.EndsWith("L") && go.name == direction.Substring(0, direction.Length - 1) + "R";
var visible = reversed || go.name == direction;
if (go.GetComponent<MeshRenderer>()) {
var anim = go.GetComponent<SkeletonAnimation>();
anim.skeleton.ScaleX = reversed ? -1 : 1;
go.GetComponent<MeshRenderer>().enabled = visible;
}
else
{
go.GetComponent<SpriteRenderer>().flipX = reversed;
go.GetComponent<SpriteRenderer>().enabled = visible;
}
}
}
}
Did you check the placement of your skeletons? This looks as if your Skeletons are not well aligned, they are jumping up and down in height or scale when switching from side to front.
True, they are not aligned in this example, but this is not the point.
The issue is which skeletons are being shown during turning (specially from right to left).
The "sprite" example uses the same images, and as you can see, it is fine.
Now after having a closer look I noticed what you meant, it was very hard to see with the animation jumping up and down at first. For the future, please playback such issue in Unity with the frame-by-frame forward button, then it's easier to see right away what goes wrong.
You are most likely missing a call to skeletonAnimation.Update(0)
here, since OnStateEnter
is called too late in the update chain. It should also be sufficient if you only call skeleton.UpdateWorldTransform();
instead of the full Update(0)
call since you did not change AnimationState.
You are right, I was planning to make a slow-motion video, but you were faster to respond.
Indeed skeleton.UpdateWorldTransform();
was the missing part.
Thanks a lot.
Glad to hear it works now, thanks for getting back to us!
BTW: This website offers a pretty comprehensive toolset for processing animated GIFs, amoung other features you can change the playback speed:
https://ezgif.com/speed