Created
November 18, 2015 17:48
-
-
Save macromaniac/0eee452f146f9be98fa0 to your computer and use it in GitHub Desktop.
Simple way to detect swipes in unity. Reference the monobehaviour and you're done.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; | |
using System; | |
public enum SwipeGesture { SwipeUp, SwipeDown, SwipeLeft, SwipeRight, None }; | |
/// <summary> | |
/// Simplest usage: | |
/// | |
/// public SwipeGestures Gestures; // Reference to MonoBehaviour | |
/// | |
/// if(Gestures.ThisFrame == SwipeGesture.SwipeUp) | |
/// DoSomething(); | |
/// | |
/// </summary> | |
public class SwipeGestures : MonoBehaviour { | |
/// <summary> | |
/// E.G: Min Delta of .2 is 20% of screen | |
/// This is normalized towards the bigger screen that way you need | |
/// to move the same amount of pixels for non-square screens | |
/// </summary> | |
[SerializeField] | |
private float _minDelta = .2f; | |
/// <summary> | |
/// Set to true if you want to use mouse in addition to touch coords | |
/// </summary> | |
public bool UseMouse = true; | |
private const int mouseHash = 123456; | |
private SwipeGesture _swipeGestureThisFrame = SwipeGesture.None; | |
private int _lastFrameUpdated = 0; | |
/// <summary> | |
/// Returns the swipe gesture this frame | |
/// </summary> | |
public SwipeGesture ThisFrame { | |
//use lazy loading to ensure the input location has been updated | |
get { | |
EnsureInputsAreFactoredIn(); | |
return _swipeGestureThisFrame; | |
} | |
} | |
/// <summary> | |
/// Gets called on swipe gesture | |
/// </summary> | |
public event Action<SwipeGesture> OnSwipeGesture; | |
private Vector2 minDeltaPixels { | |
//normalized means its a swipe after N pixels, regardless of if its | |
//x or y | |
get { | |
float w = Screen.width * _minDelta; | |
float h = Screen.height * _minDelta; | |
if (w > h) | |
w = h; | |
else | |
h = w; | |
return new Vector2(_minDelta * w, _minDelta * h); | |
} | |
} | |
Dictionary<int, Vector2> _inputStartPositions; | |
void Awake() { | |
OnSwipeGesture = (a) => { }; | |
_inputStartPositions = new Dictionary<int, Vector2>(); | |
_swipeGestureThisFrame = SwipeGesture.None; | |
} | |
//Call this at least once a frame otherwise | |
// it will miss start positions | |
void EnsureInputsAreFactoredIn() { | |
if (_lastFrameUpdated < Time.frameCount) { | |
SaveStartPositions(); | |
if (Input.mousePresent && | |
UseMouse && | |
_inputStartPositions.ContainsKey(mouseHash)) { | |
var startPos = _inputStartPositions[mouseHash]; | |
var delta = ((Vector2)Input.mousePosition) - startPos; | |
if (AccountForDelta(delta)) | |
_inputStartPositions.Remove(mouseHash); | |
} | |
if (Input.touchSupported) { | |
foreach (var touch in Input.touches) { | |
if (_inputStartPositions.ContainsKey(touch.GetHashCode())) { | |
var startPos = _inputStartPositions[touch.GetHashCode()]; | |
var delta = touch.position - startPos; | |
if (AccountForDelta(delta)) | |
_inputStartPositions.Remove(touch.GetHashCode()); | |
} | |
} | |
} | |
} | |
_lastFrameUpdated = Time.frameCount; | |
} | |
void Update() { | |
EnsureInputsAreFactoredIn(); | |
} | |
// return true if accounted for delta | |
// this function sets all the variables for each delta | |
private bool AccountForDelta(Vector2 delta) { | |
if (delta.x > minDeltaPixels.x) { | |
_swipeGestureThisFrame = SwipeGesture.SwipeRight; | |
OnSwipeGesture(SwipeGesture.SwipeRight); | |
return true; | |
} | |
if (delta.x < -minDeltaPixels.x) { | |
_swipeGestureThisFrame = SwipeGesture.SwipeLeft; | |
OnSwipeGesture(SwipeGesture.SwipeLeft); | |
return true; | |
} | |
if (delta.y < -minDeltaPixels.y) { | |
_swipeGestureThisFrame = SwipeGesture.SwipeDown; | |
OnSwipeGesture(SwipeGesture.SwipeDown); | |
return true; | |
} | |
if (delta.y > minDeltaPixels.y) { | |
_swipeGestureThisFrame = SwipeGesture.SwipeUp; | |
OnSwipeGesture(SwipeGesture.SwipeUp); | |
return true; | |
} | |
return false; | |
} | |
//this function makes sure the start positions are in the dictionary | |
//You must call it every frame in case new touches are added | |
private void SaveStartPositions() { | |
foreach (var touch in Input.touches) { | |
var h = touch.GetHashCode(); | |
if (touch.phase == TouchPhase.Began) | |
_inputStartPositions.Add(h, touch.position); | |
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) | |
_inputStartPositions.Remove(h); | |
} | |
if (Input.GetMouseButtonDown(0)) { | |
_inputStartPositions.Add(mouseHash, Input.mousePosition); | |
} | |
if (Input.GetMouseButtonUp(0)) { | |
_inputStartPositions.Remove(mouseHash); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment