I'm implementing specific type of touch controller. The player needs to hold their finger on screen in order to move. Without lifting the finger, the player can swipe in different direction to change direction while still moving. Once the finger is lifted, the player stops moving.
It's been a hard time isolating specific swipes (i.e. lines drawn on screen) ignoring any other movements that are not intended to draw a line. For instance slight finger movements done when the player's finger is "stationary", they mess up my algorithm.
I thought about different approaches such as storing the last few touches and evaluate upon them to determine if there has been a swipe or not, but couldn't implement it properly.
Here's what I've tried so far. Most of the time it works fine, but often the player does erratic movement and goes absolutely the opposite direction to what I intended.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchInputHandler : AbstractInputHandler {
private const int SWIPE_MIN_DISTANCE = 35;
private Vector2 touchStartPoint;
private Vector2 touchMovePoint;
void Update () {
Touch[] touches = Input.touches;
if (touches.Length == 1) {
Touch firstTouch = touches [0];
if (firstTouch.phase == TouchPhase.Began) {
this.touchStartPoint = firstTouch.position;
fireNextDirectionChanged (currentDirection);
} else if (firstTouch.phase == TouchPhase.Moved) {
this.touchMovePoint = firstTouch.position;
if (Vector2.Distance(touchStartPoint, touchMovePoint) > SWIPE_MIN_DISTANCE) {
detectSwipeDirection ();
}
} else if (firstTouch.phase == TouchPhase.Stationary) {
touchStartPoint.x = touchMovePoint.x;
touchStartPoint.y = touchMovePoint.y;
} else if (firstTouch.phase == TouchPhase.Ended) {
fireNextDirectionChanged (Constants.Direction.NONE);
}
}
}
private void detectSwipeDirection() {
float xDiff = touchMovePoint.x - touchStartPoint.x;
float yDiff = touchMovePoint.y - touchStartPoint.y;
Constants.Direction nextDirection;
bool yGreater = Mathf.Abs(yDiff) >= Mathf.Abs(xDiff);
if (yGreater) {
// direction is up or down
nextDirection = yDiff < 0 ? Constants.Direction.DOWN : Constants.Direction.UP;
} else {
// direction is left or right
nextDirection = xDiff < 0 ? Constants.Direction.LEFT : Constants.Direction.RIGHT;
}
if (nextDirection != this.currentDirection)
{
fireNextDirectionChanged (nextDirection);
this.currentDirection = nextDirection;
}
}
}