3

I have a rigged 2D character with Sprites And Bones in Unity and I use inverse kinematics to animate it.

But if I want to flip the X-axis, my character go berserk :

IK flipping

I have a script attached to "Karateka", containing a simple Flip() function :

public void Flip(){
    facingRight = !facingRight;
    Vector3 karatekaScale = transform.localScale;
    karatekaScale.x *= -1;
    transform.localScale = karatekaScale;
}
  • "Karateka" is just a container for bones, sprites and IK targets
  • "Skeleton" contains the Skeleton script from Sprite And Bones
  • "Right leg bone", "Right lower leg bone", etc. have bone and IK scripts
  • "Right leg", "Right lower leg", etc. are the sprites
  • "IK" contains all the IK targets

I have the same kind of effect with an other IK script, Simple CCD, from Unite 2014 - 2D Best Practices In Unity, so I may just do something stupid.

What can I do to properly flip my character?

EDIT (for Mark) :

I got it to work using this :

public void Flip(){
    facingRight = !facingRight;
    /*
    Vector3 karatekaScale = transform.localScale;
    karatekaScale.x *= -1;
    transform.localScale = karatekaScale;
    */

    GameObject IK = GameObject.Find ("IK");
    GameObject skeleton = GameObject.Find ("Skeleton");

    Vector3 ikScale = IK.transform.localScale;
    ikScale.x *= -1;
    IK.transform.localScale = ikScale;

    if (facingRight) {
        skeleton.transform.localEulerAngles = new Vector3(skeleton.transform.localEulerAngles.x, 180.0f, skeleton.transform.localEulerAngles.z);
    } else {
        skeleton.transform.localEulerAngles = new Vector3(skeleton.transform.localEulerAngles.x, 0.0f, skeleton.transform.localEulerAngles.z);
    }
}
Cyrille
  • 13,905
  • 2
  • 22
  • 41
  • Is there a reason you want to code this instead of using Sprite Renderer's flipX/flipY? https://docs.unity3d.com/ScriptReference/SpriteRenderer.html If you do with that, does the same thing happen? Did you double-check your IKs and pole targets (for every IK and bone)? –  Oct 10 '16 at 13:51
  • I don't understand : I do not have any `SpriteRenderer` component on my "karateka" `GameObject`. I have 3 `SpriteRenderer` on each limb (so 12 in total) + a few more for torso and head parts. For example, each "Right leg", "Right lower leg" and "Right foot" have their own `SpriteRenderer`. If I flip one, it will only be flipped locally. I tried adding an elmpty Sprite Renderer on the top "karateka" object, with no luck. I tried`GetComponent ().flipX = true;` too. I will check again all my objects, but, since it's working on one direction, I think it should work on both. – Cyrille Oct 10 '16 at 14:27
  • It really looks like you don't flip everything and/or don't reset bones correctly. The animation is too fast for my eyes but it seems to me some of the bones stuck in place and keep pointing toward the same direction (i.e. not flipped and not moved - is your sprite's origin at 0?). As you do this from code, you could also dump all data from the whole tree with a Debug.Log to see what's "stuck" in position. If nothing, that's information too –  Oct 10 '16 at 14:42
  • 1
    You may have put me in the right track. Skeleton script has an "Edit mode" checkbox. When it's checked and I flip my character using `scale.x *= -1`, I can see that everything **except** the bones are flipped. So only sprites and IK targets. Now, in my Flip() function, I only flip the top "IK" GameObject and it's much better, except, that my sprites are still in the wrong direction of course. I noticed a `Flip()` button in the Sprites And Bones GameObject Inspector that flip every sprites. I'm still not able to get it triggered from code though. In worst case, I will loop on all SpriteRenderer – Cyrille Oct 10 '16 at 15:26
  • 1
    I got it to work using the code I put at the end of my question. You can copy/past it into an answer so I can accept it. Thank you for your time! – Cyrille Oct 10 '16 at 15:38
  • Great news you fixed that (hope I can buy the game soon! Thanks again for sharing and still glad I could help :) –  Oct 10 '16 at 15:47

2 Answers2

2

Okay, so as we discussed in comments, just to sum it up:
1) You don't flip everything and/or don't reset bones correctly, that's why the animation "falls apart" on flipping
2) One can do a SpriteRenderer.flip[X/Y] but this should be done on every element of the sprite
3) Skeleton script has an "Edit mode" checkbox. When it's checked and one flips the character using scale.x *= -1, can see that everything except the bones are flipped

And last but not least, the question got updated with the code snippet providing the "code level solution" to the issue.

Thanks for sharing all the details Cyrille as well as I'm glad I could help.

0

It is also possible to just rotate the root of the prefab (here Karateka) 180° on the Y axis.

The 2D sprite are actually 2 sided 3D mesh, rotating them 180° on the Y axis does the same as flipping the render, and if the IK are parented to the root of the object they will follow the rotation, and all the animations will work.

Jirika
  • 1