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 ![]()
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 }}