Flipping Sprites for Horizontal Movement

I’m tinkering around with setting up the basics for a Zelda-style game, and I made a spritesheet with up, down and left-facing Link sprites. For right-facing movement I want to flip the left-facing sprites horizontally, simple stuff.

I’ve set it up right now so that it applies a 180 degree Y rotation when the player moves right and it pretty much works, but I want to also make sure it does not apply this rotation to the up/down animations. So I made it enforce a 0 degree Y rotation in those cases and that pretty much works too, see demo: https://dl.dropboxusercontent.com/u/12065987/Roguelike%20Test%201%204-12-15/Web%20Build.html

And this is how I’ve written it:

  void FixedUpdate() {
    HandleMovement();
  }

  private void HandleMovement() {
    if (Input.GetButton("Stop")) {
      rigidBody.velocity = new Vector2(0, 0);
      animator.SetTrigger("stopMoving");
    } else {
      float moveHorizontal = Input.GetAxis("Horizontal");
      float moveVertical = Input.GetAxis("Vertical");
      Vector2 movement = new Vector2(moveHorizontal, moveVertical);
    
      rigidBody.velocity = movement * moveSpeed;
      AnimateMovement(movement);
    }
  }

private void AnimateMovement(Vector2 movement) {
    if (movement.magnitude == 0) {
      animator.SetTrigger("stopMoving");
      return;
    }

    bool isHorizontal = Mathf.Abs(movement.x) > Mathf.Abs(movement.y);
    if (isHorizontal) {
      animator.SetTrigger("walkSide");
      // Flip horizontally if facing right
      float rotateY = movement.x > 0 ? 180 : 0;
      rigidBody.transform.rotation = Quaternion.Euler(0, rotateY, 0);
    } else {
      animator.SetTrigger(movement.y > 0 ? "walkUp" : "walkDown");
      rigidBody.transform.rotation = Quaternion.Euler(0, 0, 0);
    }
  }

However there’s a catch - if you’re moving right and then start holding down, there’s a brief moment where you can see the rotation happen before the animation changes. i.e. the effects of line 34 are visible before the effects of line 33, and for a frame or two he is actually facing left while moving down/right.

Yes, I’m a perfectionist and this bugs me :slight_smile: Anyone know of a way that I can make sure that this rotation is always applied at the same time as the animation change? Or is there a better way I should be handling this?

You could breakout the effect across two frames. Do your line 33 animation but for line 34 just set a flag bRotationNeeded or whatever. Then in Update check and if you need to do a rotation take care of it. That may help them to sync up. The right way to do this may be to simply include the rotation in the animation itself. Have all of the up frames flip the sprite as needed

Hopefully some of that helps. Things like this are why I don’t use the Animator or Physics systems. Hate to rely on other systems where the exact behavior is an unknown and kinda quirky at least based on what I want it to do. :wink:

Yeah I hear you, but I do hate reinventing the wheel when I can use a system that’s built to scale for much more complexity than I know I need yet. Turns out it was a bad idea to try to sync up two different systems like this, but instead the Animator itself supports rotation, so for posterity I fixed it like so:

  1. Create a copy of the left animation
  2. In the Animation window, Add Property → Transform → Rotation
  3. Set Y rotation to 180 in both keyframes

So I do need different animations but at least I don’t have to duplicate my sprites.

By the way, is there a specific need for rotating about 180 degrees on the Y axis? You could also just set the scale to -1 on the X axis.

1 Like