I'm trying to create a football game where the user will make a flick gesture in order to kick the ball. I'm quite new to developing games in unity3d, I have successfully made a moving ball, added some rotation, gravity and some basic input (the ball follows the touch coordinates). How can I achieve the flick gesture?
3 Answers
If you want to stay in the "Unity state of mind" and keep your code platform independent (even if just so you can easily test on your desktop), I found the easiest way to handle gestures is using one of the gesture plugins.
I can recommend two:
- TouchKit by Prime31 - free and open source
- Input.Touches - available in the asset store, not free.
Also worth mentioning is TouchScript a very professional free library, but may be an overkill for your needs.
At my company we use FingerGestures
Using that add-on, you'd be listening for and responding to events like: FingerGestures.OnFingerDragBegin += FingerGestures_OnFingerDragBegin; FingerGestures.OnFingerDragMove += FingerGestures_OnFingerDragMove; FingerGestures.OnFingerDragEnd += FingerGestures_OnFingerDragEnd;
Use the position returned from drag begin and drag end to determine the magnitude and direction of the drag, and record the start and end times in the event handlers to see how fast the gesture was. A drag done quickly is a flick.
A nice resource regarding basics of flick gesturing at MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/ms694980%28v=vs.85%29.aspx
Regarding Unity3D, you can take help from the following resource http://forum.unity3d.com/threads/53587-Flick-and-Slide
The following code may help you
// one finger gestures
if (iPhoneInput.touchCount == 1) {
// finger data
iPhoneTouch f0 = iPhoneInput.GetTouch(0);
// finger delta
Vector3 f0Delta = new Vector3(f0.deltaPosition.x, -f0.deltaPosition.y, 0);
// if finger moving
if (f0.phase == iPhoneTouchPhase.Moved) {
// compute orbit speed
orbitSpeed += (f0Delta + f0Delta * distWeight) * orbitScreenToWorldRatio * Time.deltaTime;
}
}
// two fingers gestures
else if (iPhoneInput.touchCount == 2) {
// fingers data
iPhoneTouch f0 = iPhoneInput.GetTouch(0);
iPhoneTouch f1 = iPhoneInput.GetTouch(1);
// fingers positions
Vector3 f0Pos = new Vector3(f0.position.x, f0.position.y, 0);
Vector3 f1Pos = new Vector3(f1.position.x, f1.position.y, 0);
// fingers movements
Vector3 f0Delta = new Vector3(f0.deltaPosition.x, f0.deltaPosition.y, 0);
Vector3 f1Delta = new Vector3(f1.deltaPosition.x, f1.deltaPosition.y, 0);
// fingers distance
float f0f1Dist = Vector3.Distance(f0.position, f1.position);
// if both fingers moving
if (f0.phase == iPhoneTouchPhase.Moved && f1.phase == iPhoneTouchPhase.Moved) {
// fingers moving direction
Vector3 f0Dir = f0Delta.normalized;
Vector3 f1Dir = f1Delta.normalized;
// dot product of directions
float dot = Vector3.Dot(f0Dir, f1Dir);
// if fingers moving in opposite directions
if (dot < -0.7f) {
float pinchDelta = f0f1Dist - lastf0f1Dist;
// if fingers move more than a threshold
if (Mathf.Abs(pinchDelta) > 2) {
// if pinch out, zoom in
if (f0f1Dist > lastf0f1Dist && zoomDistance > zoomNearLimit) {
zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
}
// if pinch in, zoom out
else if (f0f1Dist < lastf0f1Dist && zoomDistance < zoomFarLimit) {
zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
}
}
// detect twist
if (f0Delta.magnitude > 2 && f1Delta.magnitude > 2) {
// homemade algorithm works, but needs code review
Vector3 fingersDir = (f1Pos - f0Pos).normalized;
Vector3 twistNormal = Vector3.Cross(fingersDir, Vector3.forward);
Vector3 twistAxis = Vector3.Cross(fingersDir, twistNormal);
float averageDelta = (f0Delta.magnitude + f1Delta.magnitude) / 2;
if (Vector3.Dot(f0Dir, twistNormal) > 0.7f) {
twistSpeed = twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
}
else if (Vector3.Dot(f0Dir, twistNormal) < -0.7f) {
twistSpeed = -twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
}
}
}
}
// record last distance, for delta distances
lastf0f1Dist = f0f1Dist;
// decelerate zoom speed
zoomSpeed = zoomSpeed * (1 - Time.deltaTime * 10);
}