# Detect left and right movement of sprite

I have a sprite of ball which moves when a player tap and holds the ball and move finger on the screen. I have a attached animations on it. straight, left, right and when the ball hits something.

Here is my code: ball.cs

 public RuntimeAnimatorController straight;
public RuntimeAnimatorController left;
public RuntimeAnimatorController right;
public RuntimeAnimatorController ballHit;

Animator animator;
Vector2 prevPos;

private void Start()
{
animator = gameObject.GetComponent<Animator>();
}

void Update ()
{

//Gets the world position of the mouse on the screen
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

//Checks whether the mouse is over the sprite
bool overSprite = this.GetComponent<SpriteRenderer>().bounds.Contains(mousePosition);
if(GameObject.Find("GameController").GetComponent<brickMovement>().gameOver == true)
{

animator.applyRootMotion = true;
animator.updateMode = AnimatorUpdateMode.UnscaledTime;
animator.runtimeAnimatorController = ballHit;
}
//If it's over the sprite
if (overSprite)
{
//If we've pressed down on the mouse (or touched on the iphone)
if (Input.GetButton("Fire1") && GameObject.Find("GameController").GetComponent<brickMovement>().gamepaused == false && GameObject.Find("GameController").GetComponent<brickMovement>().gameOver == false)
{
float x = Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
float y = Camera.main.ScreenToWorldPoint(Input.mousePosition).y;
//Set the position to the mouse position
prevPos = this.transform.position;

//Debug.Log(animator.runtimeAnimatorController);
if ((x > -1.938 && y > -4.51) && (x < 1.98 && y < 4.5))
{
//Debug.Log("Previous Pos: " + prevPos.x);
Debug.Log(IsThisObjectMoving());
if (this.transform.position.x < 0 && IsThisObjectMoving())
{
animator.runtimeAnimatorController = left;
}
else if (this.transform.position.x > 0 && IsThisObjectMoving())
{
animator.runtimeAnimatorController = right;
}
else if (this.transform.position.x == prevPos.x)
{
animator.runtimeAnimatorController = straight;
}
this.transform.position = new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
Camera.main.ScreenToWorldPoint(Input.mousePosition).y,
0.0f);
}
}
}
}

bool IsThisObjectMoving()
{
Vector3 sek0pos;
Vector3 sek1pos;

sek0pos = gameObject.transform.position;
StartCoroutine(delay());
sek1pos = gameObject.transform.position;

if ((sek1pos.x - sek0pos.x) > 0f)
return true;
else
return false;
}

/*

Make function out of the above function that will check if object is
moving left or right.

*/
IEnumerator delay()
{
yield return new WaitForSeconds(1.0f);
}


I am having issue in detecting if ball is moving left or right. When ball is not moving straight animation should be played. but when it is the respective direction animation should be played.

Secondly when I do a hit animation it ends quickly without getting played properly.

• Any reason why you do this with an animator instead of the physics system? I feel like you're making it harder for yourself than it needs to be.
– iQew
May 29 '19 at 7:22
• Well found out this and that is why I did. Dont know how to do it with physics May 29 '19 at 7:40
• What do your animations do? We might be able to suggest simpler ways to achieve the same ends. (For example, you probably don't need four animator controllers to do the job of one or zero) May 29 '19 at 8:26

Note that the IEnumerator delay() in your code doesn't do anything. In the IsThisObjectMoving() function, calling StartCoroutine(delay()) returns immediately, so sek0pos and sek1pos are always the exact same.

If you want to add a 1-second delay within the IsThisObjectMoving() function, you can mark this function as async Task<bool> (including System.Threading.Tasks), use await Task.Delay(1000) instead of using your delay() IEnumerator, and using the function within an await statement: if(await IsThisObjectMoving()){ /*...*/ } (the function in which this is called will need to be marked async as well). The function will then return after one full second. Note that you'd need .NET 4.x to be able to use async functionality natively in Unity.

Depending on what you want to do exactly, you may want to look into other alternatives. For example, you can sample consecutive positions within different frames in Update(), or discard Update() and rewrite it as a coroutine which runs infinitely on the GameObject, sampling the position every second; something like so:

void Start(){
StartCoroutine(positionSample());
}

IEnumerator positionSample(){
Vector3 previousPosition = transform.position;
Vector3 currentPosition;

while(true){
yield return new WaitForSeconds(1);
currentPosition = transform.position;

// use the two positions to determine what you need

previousPosition = currentPosition;
}
}

• yes thanks man. I used this approach instead of Update() and the animation switch is smooth. thanks May 30 '19 at 2:19