Skip to content

Gestures

Valentin Simonov edited this page Jul 30, 2017 · 26 revisions

In TouchScript all gesture recognition is done by components which inherit from Gesture class. Gestures are Monobehaviours, they are attached to GameObjects in scene and they receive touch input from TouchManager.

In other words if you want an object to react to taps attach TapGesture to it.

What is a Gesture

A gesture can be either discrete or continuous.

Discrete gestures are recognized and immediately reset afterwards. An example of a discrete gesture is TapGesture. Which fires when user taps an object.

Continuous gestures continue to send events after they are recognized. An example of a continuous gesture is TransformGesture. It begins when movement starts and continues to dispatch delta changes afterwards.

A gesture is a state machine. It gets touch input and changes state when it recognizes the pattern it was made to recognize. A gesture can be in one of the following states:

  • Idle — hasn't started recognizing the pattern yet (either because there are not enough pointers on the target or the gesture is not interested in them),
  • Possible — gesture has started recognizing the pattern but hasn't succeeded yet,
  • Begancontinuous gesture has begun,
  • Changedcontinuous gesture updated,
  • Endedcontinuous gesture ended,
  • Recognizeddiscrete gesture recognized its pattern,
  • Cancelled — gesture was cancelled by the system,
  • Failed — gesture failed to recognize its pattern or was forced to fail by another gesture.

If you want to know more about how gestures get pointer input, please read this article.

Working with gestures

After you add a Gesture to a GameObject, you should subscribe to its events. Most gestures have special events or send named messages when they are recognized. Also all of them dispatch StateChanged events.

  • To subscribe for a gesture event you just add an event handler like this:
gesture.StateChanged += gestureStateChangedHandler;

Where the handler method must have the following signature:

void gestureStateChangedHandler(object sender, GestureStateChangeEventArgs e)

GestureStateChangeEventArgs has State and PreviousState properties.

  • If you want to receive messages using Unity's SendMessage mechanism, first, you need to make sure that Use SendMessage check box is checked on the gesture. After that you need to declare a method in your script with signature:
void OnGestureStateChanged(Gesture sender)

Which will be called every time the gesture changes state. To find out the current state use sender.State property.

But if you are using a specific gesture, for example TapGesture, you can use its Tapped event which is essentially the same as Gesture.GestureState.Recognized but easier to remember.

Example code:

private void OnEnable()
{
    GetComponent<TapGesture>().Tapped += tappedHandler;
}

private void OnDisable()
{
    GetComponent<TapGesture>().Tapped -= tappedHandler;
}

private void tappedHandler(object sender, EventArgs e)
{
}

For more info about handling gesture events look at Tutorials section.

Gestures bundled with TouchScript

TouchScript includes the following gestures.

DISCRETE:

  1. Tap Gesture — recognizes a single/double/triple tap.
    Events: Tapped, Messages: OnTap.
  2. Press Gesture — recognizes when a user presses an object, i.e. when the first touch lands on it.
    Is automatically friendly with any other gesture.
    Events: Pressed, Messages: OnPress.
  3. Release Gesture — recognizes when a user releases an object, i.e. when the last touch is lifted off.
    Is automatically friendly with any other gesture.
    Events: Released, Messages: OnRelease.
  4. LongPress Gesture — recognizes when a user holds touches on an object for a specific time interval.
    Events: LongPressed, Messages: OnLongPress.
  5. Flick Gesture — recognizes a flick gesture in any direction.
    Events: Flicked, Messages: OnFlick.

CONTINUOUS:

  1. Transform Gesture — recognizes a transform gesture i.e. translation, rotation, scaling and their combinations.
    Events: TransformStarted, Transformed, TransformCompleted; Messages: OnTransformStart, OnTransform, OnTransformComplete.
  2. Screen Transform Gesture — same as Transform Gesture but in screen coordinates.
    Events: TransformStarted, Transformed, TransformCompleted; Messages: OnTransformStart, OnTransform, OnTransformComplete.
  3. Pinned Transform Gesture — similar to Transform Gesture but if an object was pinned to its center and couldn't move only rotate around pin point and scale.
    Events: TransformStarted, Transformed, TransformCompleted; Messages: OnTransformStart, OnTransform, OnTransformComplete.
  4. Meta Gesture — redispatches all touch events for an object it is attached to as separate events. If you are considering to use MetaGesture it's usually better to create a custom gesture instead.
    Events: TouchBegan, TouchMoved, TouchEnded, TouchCancelled; Messages: OnTouchBegan, OnTouchMoved, OnTouchEnded, OnTouchCancelled.

TransformGesture, _PinnedTransformGesture and ScreenTransformGesture use only the first one or two touch points which is fine for a small mobile device but might look odd on a big touch screen, this is why they all have Clustered* counterparts which combine touch points to clusters and work with the centers of these clusters instead of individual touches.

Making gestures work together

Usually when a gesture recognizes it stops all other gestures on the same GameObject and its parents from recognizing. The gesture which starts first gets exclusive rights. It's a good way to make sure that, for example, Transform Gesture stops Tap Gesture from recognizing when the object is being dragged.

But sometimes you want two or more gestures work together. Such gestures are called Friendly within the library.
There are two ways to make gestures friendly:

  1. Add one to another one's Friendly Gestures list in inspector by dragging and dropping.
  2. Call gesture1.AddFriendlyGesture(gesture2);.

It doesn't matter what gesture you added to another one's Friendly Gestures list. If one gesture is friendly with another, the second one will automatically be friendly with the first one.

Requiring a gesture to fail

If you want gesture A to recognize only when gesture B fails you can set B to A's RequireGestureToFail in inspector or via script. In this case gesture A won't recognize until gesture B fails.

It's a way to implement single and double taps on the same object.

But this behavior adds some delay to taps because double tap must fail first.

Precise control for gesture recognition

Every gesture has IGestureDelegate Delegate property. IGestureDelegate is an interface which allows an external object to control a gesture.

If Delegate is set it gets asked every time a gesture wants to do something:

  • bool ShouldReceiveTouch(Gesture gesture, ITouch touch); is called when a new touch is going to be added to the gesture. You can discard this touch if you want.
  • bool ShouldBegin(Gesture gesture); is called when the gesture is about to begin. You can prevent it from beginning.
  • bool ShouldRecognizeSimultaneously(Gesture first, Gesture second); is called when two gestures want to work simultaneously. Usually this is ruled by Friendly Gestures property, but you can override this behavior using a Delegate.

Writing your own gestures

Please refer to this tutorial if you want to write your own gesture.