Swipe on the part of the screen

Hi. I have 2 players in my game. I want to make separated controls for them. If I swipe left or right my player would go left or right. But I want same with my second player. So is there any way I can separate controls, for first player I should swipe on the left part of the screen and for the second, I should swipe on the right part of the screen? I already have swipe controls in my script, I only need to detect on which part of the screen player swipes. Greetings!

foreach(Touch touch in Input.touches)
       {
         if (touch.phase == TouchPhase.Began)
         {
              fp = touch.position;
              lp = touch.position;
         }
              if (touch.phase == TouchPhase.Moved )
              {
                  lp = touch.position;
              }
              if(touch.phase == TouchPhase.Ended)
              {
                   if((fp.x - lp.x) > 80) // left swipe
                   {
 
                   }
                   else if((fp.x - lp.x) < -80) // right swipe
                  {
 
                  }

I think you can’t achieve that.

I don’t know if this will work, as i have only worked on Mobile a little… but it’s just my theory.

Divide “Screen Width” by two and store it.

Check the position of the first two touches:

Touch 1:
if > “Screen Width / 2”, Touch 1 = Player 2
if < “Screen Width / 2”, Touch 1 = Player 1

Touch 2:
if > “Screen Width / 2”, Touch 2 = Player 2
if < “Screen Width / 2”, Touch 2 = Player 1

Then carry on doing your check to see if each touch has moved 80 pixels either way from their original location.

Sure you could measure where the swipe is occurring, if it is the left side, pass to player x, swipe left, right. And vice versa.

Maybe this photo will explain better what I want to acheieve.

1595114--95912--$photo.png

This is certainly possible. You would just need two sets of variables to keep track of player swiping actions.

public enum SwipeDirection {
    Up,
    Right,
    Down,
    Left,
}

public delegate void SwipeEventHandler(SwipeDirection direction, Vector2 anchor, Vector2 target);

public sealed class PlayerSwipe : MonoBehaviour {
    public float swipeThreshold = 30;

    public bool isSwiping { get; private set; }
    public Vector2 anchorPoint { get; private set; }

    // Set screen rect depending upon player.
    public Rect screenArea;
    // Subscribe to this event!!
    public event SwipeEventHandler FingerSwiped;

    private int _fingerId;

    private void Update() {
        if (isSwiping)
            TrackSwiping();
        else
            CheckForTouchDown();
    }

    private void CheckForTouchDown() {
        if (isSwiping)
            return;

        int touchCount = Input.touchCount;
        for (int i = 0; i < touchCount; ++i) {
            var touch = Input.GetTouch(i);
            if (touch.phase == TouchPhase.Began  screenArea.Contains(touch.position)) {
                isSwiping = true;
                _fingerId = touch.fingerId;
                anchorPoint = touch.position;
                break;
            }
        }
    }

    public void Cancel() {
        isSwiping = false;
    }

    private Touch GetInfoForTrackedTouch() {
        if (!isSwiping)
            return null;

        int touchCount = Input.touchCount;
        for (int i = 0; i < touchCount; ++i) {
            var touch = Input.GetTouch(i);
            if (touch.fingerId == _fingerId)
                return touch;
        }

        return null;
    }

    private void TrackSwiping() {
        var touch = GetInfoForTrackedTouch();
        if (touch == null) {
            // Info is missing for some reason, cancel swiping gesture!
            Cancel();
            return;
        }

        if (touch.phase == TouchPhase.Moved) {
            var delta = touch.position - anchorPoint;
            var abs = new Vector2(Mathf.Abs(delta.x), Mathf.Abs(delta.y));

            SwipeDirection direction;

            if (abs.x >= swipeThreshold || abs.y >= swipeThreshold) {
                if (abs.x > abs.y) {
                    // Horizontal swipe!
                    if (delta.x > 0)
                        direction = SwipeDirection.Right;
                    else
                        direction = SwipeDirection.Left;
                }
                else {
                    // Vertical swipe!
                    if (delta.y > 0)
                        direction = SwipeDirection.Up;
                    else
                        direction = SwipeDirection.Down;
                }

                Cancel();

                // Invoke subscribed event handlers!
                if (FingerSwiped != null)
                    FingerSwiped(direction, anchorPoint, touch.position);
            }
        }
    }
}

And then usage example:

public class PlayerBehaviour : MonoBehaviour {
    public int playerNumber;

    private PlayerSwipe _swipeHandler;

    private void Awake() {
        _swipeHandler = GetComponent<PlayerSwipe>();
        _swipeHandler.FingerSwiped += OnFingerSwiped;

        if (playerNumber == 1)
            _swipeHandler.screenArea = new Rect(0, 0, Screen.width / 2, Screen.height);
        else
            _swipeHandler.screenArea = new Rect(Screen.width / 2, 0, Screen.width / 2, Screen.height);
    }

    private void OnDisable() {
        _swipeHandler.FingerSwiped -= OnFingerSwiped;
    }

    private void OnFingerSwiped(SwipeDirection direction, Vector2 anchor, Vector2 target) {
        // Swipe occurred for this player!
    }
}

With the above you would need to attach both of these components to your player game objects.

Disclaimer: The above was entered directly into the forum post and has not been tested.

I hope that this helps :slight_smile:

Thank you for your help! I get these errors:
PlayerSwipe.cs(140,49): error CS0037: Cannot convert null to UnityEngine.Touch' because it is a value type PlayerSwipe.cs(167,32): error CS0037: Cannot convert null to UnityEngine.Touch’ because it is a value type
PlayerSwipe.cs(182,19): error CS0019: Operator ==' cannot be applied to operands of type UnityEngine.Touch’ and `null’

These lines are:

private Touch GetInfoForTrackedTouch() {
	       if (!isSwiping)
		140. 	return null;
  1. and 167. are the same (return null;)
 182.  if (touch == null) {			
			            // Info is missing for some reason, cancel swiping gesture!
				           Cancel();
			           return;

Or if it’s going to be easier, in your code above these lines are 52, 61 and 66 :slight_smile:

Sorry about that, I forgot that this was a value-type rather than a reference-type.

Here, I have refactored the code a little for you:

public enum SwipeDirection {
	Up,
	Right,
	Down,
	Left,
}

public delegate void SwipeEventHandler(SwipeDirection direction, Vector2 anchor, Vector2 target);

public sealed class PlayerSwipe : MonoBehaviour {
	public float swipeThreshold = 30;

	public bool isSwiping { get; private set; }
	public Vector2 anchorPoint { get; private set; }

	// Set screen rect depending upon player.
	public Rect screenArea;
	// Subscribe to this event!!
	public event SwipeEventHandler FingerSwiped;

	private int _fingerId;

	private void Update() {
		if (Input.touchCount == 0)
			return;

		bool didUpdateTrackingMotion = false;

		int touchCount = Input.touchCount;
		for (int i = 0; i < touchCount; ++i) {
			var touch = Input.GetTouch(i);

			if (!isSwiping) {
				if (touch.phase == TouchPhase.Began  screenArea.Contains(touch.position)) {
					CheckForTouchDown(touch);
					didUpdateTrackingMotion = true;
					break;
				}
			}
			else if (touch.fingerId == _fingerId) {
				TrackSwiping(touch);
				didUpdateTrackingMotion = true;
				break;
			}
		}

		if (isSwiping  !didUpdateTrackingMotion)
			Cancel();
	}

	private void CheckForTouchDown(Touch touch) {
		isSwiping = true;
		_fingerId = touch.fingerId;
		anchorPoint = touch.position;
	}

	public void Cancel() {
		isSwiping = false;
	}

	private void TrackSwiping(Touch touch) {
		switch (touch.phase) {
			case TouchPhase.Moved:
				var delta = touch.position - anchorPoint;
				var abs = new Vector2(Mathf.Abs(delta.x), Mathf.Abs(delta.y));

				SwipeDirection direction;

				if (abs.x >= swipeThreshold || abs.y >= swipeThreshold) {
					if (abs.x > abs.y) {
						// Horizontal swipe!
						if (delta.x > 0)
							direction = SwipeDirection.Right;
						else
							direction = SwipeDirection.Left;
					}
					else {
						// Vertical swipe!
						if (delta.y > 0)
							direction = SwipeDirection.Up;
						else
							direction = SwipeDirection.Down;
					}

					Cancel();

					// Invoke subscribed event handlers!
					if (FingerSwiped != null)
						FingerSwiped(direction, anchorPoint, touch.position);
				}
				break;

			case TouchPhase.Canceled:
			case TouchPhase.Ended:
				Cancel();
				break;
		}
	}
}

Let me know how it goes!!

You can monitor which sidet he swipe is occurring by either, checking the finger position at swipe beginning. If on left side, left player move.

The oer is to use colliders and raycasts. The colliders, two of them, act like btns. When you finger goes down, shoot a raycast. If raycast hits btn left, you move player left (side) and vice versa.

I didn’t get any errors :smile: Thank you very much for this! Just one more question :stuck_out_tongue:
I actually have animations for left and right and basicly when player swipes left I want to play animation for left. I had that in my script and I know how to play animation with script. I’m just wondering where should I put code for playing animation ? I had this before

if((fp.x - lp.x) > 80) // left swipe

                 {
                        animation.Play (animationLeft.name);
                 }

Place this in your event handler:

private void OnFingerSwiped(SwipeDirection direction, Vector2 anchor, Vector2 target) {
    switch (direction) {
        case SwipeDirection.Left:
            // Trigger leftward swipe animation!
            break;
        case SwipeDirection.Right:
            // Trigger rightward swipe animation!
            break;
    }
}

I fixed an error in my previous post a few minutes after I posted it. Could you just make sure that you copied the latest version.

I placed the begin and track functionality back-to-front, so it would not have worked properly.

Yes, I have latest version of your code. I’m gonna try that and let you know if it’s working.

Thank you so so much :smile: It’s working perfect! I’m glad we have people like you here :smile:

No problem it was my pleasure and I am happy that it worked for you :slight_smile: