Created
April 2, 2012 07:29
-
-
Save boj/2281404 to your computer and use it in GitHub Desktop.
Unity3d Touch Tracking
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; | |
using System.Collections.Generic; | |
/** | |
Spits out a string based on gesture directions regardless of size or location. | |
Example: | |
TOP LEFT -> BOTTOM RIGHT SLASH = 13 | |
TOP RIGHT -> BOTTOM LEFT SLASH = 32 | |
COUNTER CLOCKWISE CIRCLE FROM TOP = 23142 | |
CLOCKWISE CIRCLE FROM TOP = 13241 | |
*/ | |
public class GestureTracker : MonoBehaviour { | |
private bool fingerIsDown = false; | |
private Vector3 touchStart; | |
private Vector3 touchEnd; | |
private float deviationCheckDistance = 5.0f; | |
private Vector3 lastDeviationCheck = Vector3.zero; | |
public float touchPatternResetTime = 3.0f; | |
private float touchPatternTime = 0.0f; | |
private string touchPattern = ""; | |
private string touchPatternChain = ""; | |
// pattern chains | |
private string[] slashUpChain = new string[5] { "4", "41", "42", "14", "24" }; | |
private string[] crossSlashChain = new string[6] { "13,23", "23,13", "32,31", "31,32", "13,32", "32,13" }; | |
private string[] sideSlashChain = new string[2] { "1", "2" }; | |
private string[] circleChain = new string[4] { "23142", "13241", "24132", "14231" }; | |
// registered pattern listeners | |
private List<GameObject> slashUpListeners = new List<GameObject>(); | |
private List<GameObject> crossSlashListeners = new List<GameObject>(); | |
private List<GameObject> sideSlashListeners = new List<GameObject>(); | |
private List<GameObject> circleListeners = new List<GameObject>(); | |
void Update() { | |
// touch start | |
if (!fingerIsDown && Input.GetButtonDown("Fire1")) { | |
fingerIsDown = true; | |
touchStart = Camera.main.ScreenToWorldPoint(Input.mousePosition); | |
touchStart.z = -1; | |
lastDeviationCheck = touchStart; | |
} | |
// touch middle | |
if (fingerIsDown && Input.GetButton("Fire1")) { | |
touchPatternTime = 0.0f; // reset touch pattern time | |
Vector3 touchCurrent = Camera.main.ScreenToWorldPoint(Input.mousePosition); | |
float diffX = Mathf.Abs(touchCurrent.x - lastDeviationCheck.x); | |
float diffY = Mathf.Abs(touchCurrent.y - lastDeviationCheck.y); | |
bool deviated = false; | |
if (diffX > deviationCheckDistance) { | |
// RIGHT -> LEFT | |
if (touchCurrent.x > lastDeviationCheck.x) { | |
RecordPattern("1"); | |
deviated = true; | |
} | |
// LEFT -> RIGHT | |
if (touchCurrent.x < lastDeviationCheck.x) { | |
RecordPattern("2"); | |
deviated = true; | |
} | |
} | |
if (diffY > deviationCheckDistance) { | |
// TOP -> BOTTOM | |
if (touchCurrent.y < lastDeviationCheck.y) { | |
RecordPattern("3"); | |
deviated = true; | |
} | |
// BOTTOM -> TOP | |
if (touchCurrent.y > lastDeviationCheck.y) { | |
RecordPattern("4"); | |
deviated = true; | |
} | |
} | |
if (deviated) { | |
lastDeviationCheck = touchCurrent; | |
} | |
} | |
// touch end | |
if (fingerIsDown && Input.GetButtonUp("Fire1")) { | |
fingerIsDown = false; | |
touchEnd = Camera.main.ScreenToWorldPoint(Input.mousePosition); | |
touchEnd.z = -1; | |
// check patterns on mouse up | |
if (touchPattern != "") { | |
ProcessPattern(touchPattern); | |
} | |
} | |
touchPatternTime += 0.1f; | |
// if we are over the pattern matching time limit the user did something else | |
if (touchPatternTime > touchPatternResetTime) { | |
ResetPattern(); | |
} | |
} | |
void RecordPattern(string thisPattern) { | |
switch (touchPattern.Length) { | |
case 0: | |
touchPattern += thisPattern; | |
break; | |
case 1: | |
if (thisPattern != touchPattern) { | |
touchPattern += thisPattern; | |
} | |
break; | |
default: | |
string lastCheck1 = touchPattern.Substring(touchPattern.Length - 2, 1); | |
string lastCheck2 = touchPattern.Substring(touchPattern.Length - 2, 2); | |
if (thisPattern != lastCheck1 && lastCheck1 + thisPattern != lastCheck2) { | |
touchPattern += thisPattern; | |
} | |
break; | |
} | |
} | |
void ResetTouch() { | |
touchPatternTime = 0.0f; | |
touchPattern = ""; | |
} | |
void ResetPattern() { | |
touchPatternChain = ""; | |
ResetTouch(); | |
} | |
void ProcessPattern(string pattern) { | |
ResetTouch(); | |
if (touchPatternChain.Length > 0) { | |
touchPatternChain += "," + pattern; | |
} else { | |
touchPatternChain = pattern; | |
} | |
// slash up | |
foreach (string chain in slashUpChain) { | |
if (touchPatternChain == chain) { | |
ResetPattern(); | |
ProcessSlashUp(); | |
return; | |
} | |
} | |
// cross slash | |
foreach (string chain in crossSlashChain) { | |
if (touchPatternChain == chain) { | |
ResetPattern(); | |
ProcessCrossSlash(); | |
return; | |
} | |
} | |
// side slash | |
foreach (string chain in sideSlashChain) { | |
if (touchPatternChain == chain) { | |
ResetPattern(); | |
ProcessSideSlash(); | |
return; | |
} | |
} | |
// circle | |
foreach (string chain in circleChain) { | |
if (touchPatternChain == chain) { | |
ResetPattern(); | |
ProcessCircle(); | |
return; | |
} | |
} | |
} | |
void ProcessSlashUp() { | |
for (int i = 0; i < slashUpListeners.Count; i++) { | |
slashUpListeners[i].SendMessage("Activate", touchEnd); | |
} | |
} | |
void ProcessCrossSlash() { | |
for (int i = 0; i < crossSlashListeners.Count; i++) { | |
crossSlashListeners[i].SendMessage("Activate"); | |
} | |
} | |
void ProcessSideSlash() { | |
Vector3[] sendParams = new Vector3[2] { touchStart, touchEnd }; | |
for (int i = 0; i < sideSlashListeners.Count; i++) { | |
sideSlashListeners[i].SendMessage("Activate", sendParams); | |
} | |
} | |
void ProcessCircle() { | |
for (int i = 0; i < circleListeners.Count; i++) { | |
circleListeners[i].SendMessage("Activate"); | |
} | |
} | |
public void RegisterSlashUpListener(GameObject listener) { | |
slashUpListeners.Add(listener); | |
} | |
public void RegisterCrossSlashListener(GameObject listener) { | |
crossSlashListeners.Add(listener); | |
} | |
public void RegisterSideSlashListener(GameObject listener) { | |
sideSlashListeners.Add(listener); | |
} | |
public void RegisterCircleListener(GameObject listener) { | |
circleListeners.Add(listener); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment