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:
https://imgur.com/a/DkMOf5K
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;
}
}
}
}