[SOLVED] Animations on my ship stop working with diagonal input

Question: How can I get my ship to animate (I have 3 sprites per ship, left, right and default/idle) while allowing diagonal movement?

Basics Unity Version - 5.6.0f3

Background: So I set up my project and got my ship moving around including animations of left and right (the sprites I have have a lean left and lean right sprite) so thought it’d be cool to use them. It all worked until I looked at adding diagonal movement as I wanted my ship to be able to move up and down screen as well.

I set up my scene which allowed up/down/left/right movement and it all worked including my animations but couldn’t go diagonal. Now, I added the code to allow diagonals and that is where I got stuck and it is probably obvious what I did wrong :slight_smile:

Now, when I move left and right, no animation of the tilt left/right happen to my sprite. However, if I move in a diagonal direction, the ship tilts like it should. So question is, why does left and right no longer work but diagonal does.

You’ll notice that on the up arrow section I use an IF instead of ELSE IF. This is because if I use IF, I can move diagonal. When I use an ELSE IF, I can only move on the X or Y axis individually, not both.

My code checks to see what position the ship is in (left, right or default/idle which it top down view) and resets it to “idle” when not moving in a direction.

My PlayerController.cs file

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{

public float speed = 5.0f;
private float xMin;
private float xMax;
private float yMin;
private float yMax;
public float screenPadding = 1f;
public Sprite spriteMiddle;
public Sprite spriteLeft;
public Sprite spriteRight;
private SpriteRenderer spriteRenderer;
// Use this for initialization
void Start()
{
    spriteRenderer = GetComponent<SpriteRenderer>(); // we are accessing the SpriteRenderer that is attached to the Gameobject
    if (spriteRenderer.sprite == null) // if the sprite on spriteRenderer is null then
        spriteRenderer.sprite = spriteMiddle; // set the sprite to idle
    float distance = transform.position.z - Camera.main.transform.position.z;
    Vector3 leftmost = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance));
    Vector3 rightmost = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, distance));
    Vector3 bottommost = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance));
    Vector3 topmost = Camera.main.ViewportToWorldPoint(new Vector3(0, 1, distance));
    xMin = leftmost.x + screenPadding;
    xMax = rightmost.x - screenPadding;
    yMin = bottommost.y + screenPadding;
    yMax = topmost.y - screenPadding;
}
// Update is called once per frame
void Update()
{
    if (Input.GetKey(KeyCode.LeftArrow))
    {
        transform.position += Vector3.left * speed * Time.deltaTime;
        MovingTheSpriteLeft();
    }
    else if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.position += Vector3.right * speed * Time.deltaTime;
        MovingTheSpriteRight();
    }
    if (Input.GetKey(KeyCode.UpArrow))
    {
        transform.position += Vector3.up * speed * Time.deltaTime;
    }
    else if (Input.GetKey(KeyCode.DownArrow))
    {
        transform.position += Vector3.down * speed * Time.deltaTime;
    }
    else
    {
        StopMoving();
    }
    // Set the clamping points to stop players going out of bounds and keep them in gamespace
    float newX = Mathf.Clamp(transform.position.x, xMin, xMax);
    float newY = Mathf.Clamp(transform.position.y, yMin, yMax);
    transform.position = new Vector3(newX, newY, transform.position.z);
}
void MovingTheSpriteLeft()
{
    if (spriteRenderer.sprite == spriteMiddle) // if the spriteRenderer sprite = idle then change to moving left sprite
    {
        spriteRenderer.sprite = spriteLeft;
    }
    else
    {
        spriteRenderer.sprite = spriteMiddle; // otherwise change it back to idle
    }
}
void MovingTheSpriteRight()
{
    if (spriteRenderer.sprite == spriteMiddle) // if the spriteRenderer sprite = idle then change to moving right sprite
    {
        spriteRenderer.sprite = spriteRight;
    }
    else
    {
        spriteRenderer.sprite = spriteMiddle; // otherwise change it back to idle
    }
}
void StopMoving()
{
    spriteRenderer.sprite = spriteMiddle; // otherwise change it back to idle
}

}

I knew it’d be something simple. It was all because of my ELSE statement at the end of the key detection which was to prevent a buy from happening whereby the ship would remain in the tilted orientation if the key wasn’t pressed at certain moments.

else
{
    StopMoving();
}

I removed that and it all works great now. Animated tilting left and right as well as 8 directions of movement.

So I went looking for how to reset my ship to “idle” as it got stuck between frames sometimes and came up with this:

So instead of

else
{
   StopMoving();
}

I had this which basically checks to see if any keys are pressed and if not, return to idle:

        if(Input.anyKey == false)
        {
            StopMoving();
        }

Giving this:

    void Update()
    {
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            // transform.position += new Vector3(-speed * Time.deltaTime, 0, 0); 
            // This does the same as the line below but below option is better
            transform.position += Vector3.left * speed * Time.deltaTime;
            MovingTheSpriteLeft();
        }
        else if (Input.GetKey(KeyCode.RightArrow))
        {
            // transform.position += new Vector3(+speed * Time.deltaTime, 0, 0); 
            // This does the same as the line below but below option is better
            transform.position += Vector3.right * speed * Time.deltaTime;
            MovingTheSpriteRight();
        }
        if (Input.GetKey(KeyCode.UpArrow))
        {
            transform.position += Vector3.up * speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.position += Vector3.down * speed * Time.deltaTime;
        }
        
        if(Input.anyKey == false)
        {
            StopMoving();
        }
        // Set the clamping points to stop players going out of bounds and keep them in gamespace
        float newX = Mathf.Clamp(transform.position.x, xMin, xMax);
        float newY = Mathf.Clamp(transform.position.y, yMin, yMax);
        transform.position = new Vector3(newX, newY, transform.position.z);
    }
1 Like

Privacy & Terms