Skip to content

Instantly share code, notes, and snippets.

@n0mimono
Created September 12, 2015 15:43
Show Gist options
  • Save n0mimono/e948d2c32dd8c2b8d9df to your computer and use it in GitHub Desktop.
Save n0mimono/e948d2c32dd8c2b8d9df to your computer and use it in GitHub Desktop.
public class FlickHandler : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
[System.Serializable]
public class DetectThreshold {
public float minDistance;
public float maxDistance;
public float deltaTime;
public float deltaAng;
}
public DetectThreshold threshold;
private struct FlickAction {
public Vector2 dir;
public System.Action action;
}
private List<FlickAction> flickActions;
private struct TouchData {
public Vector2 pos;
public float time;
public TouchData DeltaTo(TouchData to) {
return new TouchData () {pos = to.pos - pos, time = to.time - time};
}
}
private Dictionary<int, TouchData> touchDowns;
public void Initialize() {
flickActions = new List<FlickAction> ();
touchDowns = new Dictionary<int, TouchData> ();
}
public void AddFlickEvent(Vector2 dir, System.Action action) {
flickActions.Add(new FlickAction(){ dir = dir.normalized, action = action });
}
public void OnPointerDown (PointerEventData eventData) {
TouchDownEvent (eventData.pointerId, eventData.position);
}
public void OnPointerUp (PointerEventData eventData) {
TouchUpEvent (eventData.pointerId, eventData.position);
}
private void TouchDownEvent(int id, Vector2 pos) {
//Debug.Log ("down: " + pos + ", " + Time.time);
touchDowns [id] = new TouchData () {pos = pos, time = Time.time};
}
private void TouchUpEvent(int id, Vector2 pos) {
//Debug.Log ("up: " + pos + ", " + Time.time);
if (!touchDowns.ContainsKey (id)) Debug.Log ("god bless you");
TouchData down = touchDowns [id];
TouchData up = new TouchData () {pos = pos, time = Time.time};
TouchData delta = down.DeltaTo (up);
if (IsValidFlick (delta)) {
List<System.Action> actions = GetActionsWith(delta.pos);
actions.ForEach(a => a());
}
}
private bool IsValidFlick(TouchData delta) {
if (delta.time > threshold.deltaTime) return false;
if (delta.pos.magnitude < threshold.minDistance) return false;
if (delta.pos.magnitude > threshold.maxDistance) return false;
return true;
}
private List<System.Action> GetActionsWith(Vector2 dir) {
Vector2 v = dir.normalized;
List<System.Action> r = flickActions
.Where(a => Vector2.Dot(v, a.dir) > Mathf.Cos(threshold.deltaAng * Mathf.Deg2Rad))
.Select(a => a.action).ToList();
return r;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment