2001 lines
70 KiB
C#
2001 lines
70 KiB
C#
// FingerGestures v2.3b
|
||
// The FingerGestures library is copyright (c) of William Ravaine
|
||
// Please send feedback or bug reports to spk@fatalfrog.com
|
||
// More FingerGestures information at http://fingergestures.fatalfrog.com
|
||
|
||
using UnityEngine;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System;
|
||
|
||
/// <summary>
|
||
/// The main interface to the FingerGestures library.
|
||
/// Most of the methods are static because FingerGestures is meant to be a singleton.
|
||
/// </summary>
|
||
public abstract class FingerGestures : MonoBehaviour
|
||
{
|
||
// If you are not familiar with events and delegates, or need a refresher, please refer to this youtube video made by the guys
|
||
// at Prime31 Studios - http://www.youtube.com/watch?v=N2zdwKIsXJs
|
||
|
||
#region Global Events (Quick Use Mode)
|
||
|
||
// The following events are wrapper/proxies for the default gesture recognizers that are automatically installed and configured at start, provided the relevant options are enabled.
|
||
// Only the most relevant data for each event are passed as arguments to the event delegate. This allows developers to quickly use FingerGestures with minimal knowledge of the inner
|
||
// workings of the library.
|
||
|
||
// The default gesture recognizers can be accessed via the FingerGestures.Defaults interface.
|
||
|
||
#region Per-Finger events
|
||
|
||
//NOTE: events in this category fire independently for each finger, regardless of the state of other fingers
|
||
// You can use FingerGestures.GetFinger(fingerIndex) to retrieve the Finger object corresponding to the fingerIndex event parameter
|
||
|
||
#region Delegates
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerDown event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerDownEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerUp event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
/// <param name="timeHeldDown">How long the finger has been held down before getting released, in seconds</param>
|
||
public delegate void FingerUpEventHandler( int fingerIndex, Vector2 fingerPos, float timeHeldDown );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerStationaryBegin event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerStationaryBeginEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerStationary event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
/// <param name="elapsedTime">How much time has elapsed, in seconds, since the last OnFingerStationaryBegin fired on this finger</param>
|
||
public delegate void FingerStationaryEventHandler( int fingerIndex, Vector2 fingerPos, float elapsedTime );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerStationaryEnd event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
/// <param name="elapsedTime">How much time has elapsed, in seconds, since the last OnFingerStationaryBegin fired on this finger</param>
|
||
public delegate void FingerStationaryEndEventHandler( int fingerIndex, Vector2 fingerPos, float elapsedTime );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingerMoveBegin, OnFingerMove, OnFingerMoveEnd events
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerMoveEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernLongPress event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerLongPressEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernTap event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerTapEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernSwipe event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="startPos">Initial position of the finger</param>
|
||
/// <param name="direction">Direction of the swipe gesture</param>
|
||
/// <param name="velocity">How quickly the finger has moved (in screen pixels per second)</param>
|
||
public delegate void FingerSwipeEventHandler( int fingerIndex, Vector2 startPos, Vector2 endPos, SwipeDirection direction, float velocity );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernDragBegin event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
/// <param name="startPos">The initial finger position on the screen.</param>
|
||
/// <remark>Since the finger has to move beyond a certain treshold distance (specified by the moveThreshold property)
|
||
/// before the gesture registers as a drag motion, fingerPos and startPos are likely to be different if you specified a non-zero moveThreshold.</remark>
|
||
public delegate void FingerDragBeginEventHandler( int fingerIndex, Vector2 fingerPos, Vector2 startPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernDragMove event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
/// <param name="delta">How much the finger has moved since the last update. This is the difference between the previous finger position and the new one.</param>
|
||
public delegate void FingerDragMoveEventHandler( int fingerIndex, Vector2 fingerPos, Vector2 delta );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnFingernDragEnd event
|
||
/// </summary>
|
||
/// <param name="fingerIndex">0-based index uniquely indentifying a specific finger</param>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void FingerDragEndEventHandler( int fingerIndex, Vector2 fingerPos );
|
||
|
||
#endregion
|
||
|
||
#region Events
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's OnDown event fires
|
||
/// </summary>
|
||
/// <seealso cref="Finger.OnDown"/>
|
||
public static /*event*/ FingerDownEventHandler OnFingerDown;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's OnUp event fires
|
||
/// </summary>
|
||
/// <seealso cref="Finger.OnUp"/>
|
||
public static /*event*/ FingerUpEventHandler OnFingerUp;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnStationaryBegin event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnStationaryBegin"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerStationaryBeginEventHandler OnFingerStationaryBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnStationary event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnStationary"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerStationaryEventHandler OnFingerStationary;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnStationaryEnd event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnStationaryEnd"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerStationaryEndEventHandler OnFingerStationaryEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnMoveBegin event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnMoveBegin"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerMoveEventHandler OnFingerMoveBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnMove event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnMove"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerMoveEventHandler OnFingerMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's default motion detector OnMoveEnd event fires
|
||
/// </summary>
|
||
/// <seealso cref="FingerMotionDetector.OnMoveEnd"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Motion"/>
|
||
public static /*event*/ FingerMoveEventHandler OnFingerMoveEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's long-press gesture recognizer OnLongPress event fires
|
||
/// </summary>
|
||
/// <seealso cref="LongPressGestureRecognizer.OnLongPress"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.LongPress"/>
|
||
public static /*event*/ FingerLongPressEventHandler OnFingerLongPress;
|
||
|
||
public static /*event*/ FingerLongPressEventHandler OnFingerLongPressing;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's drag gesture recognizer OnDragBegin event fires
|
||
/// See also: <see cref="DragGestureRecognizer.OnDragBegin"/>, <see cref="DefaultComponents.FingerComponents.Drag"/>
|
||
/// </summary>
|
||
public static /*event*/ FingerDragBeginEventHandler OnFingerDragBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's drag gesture recognizer OnDragMove event fires
|
||
/// See also:<see cref="DragGestureRecognizer.OnDragMove"/>, <see cref="DefaultComponents.FingerComponents.Drag"/>
|
||
/// </summary>
|
||
public static /*event*/ FingerDragMoveEventHandler OnFingerDragMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's <see cref="DefaultComponents.FingerComponents.Drag">default drag gesture recognizer</see> <see cref="DragGestureRecognizer.OnDragEnd"/> event fires
|
||
/// </summary>
|
||
public static /*event*/ FingerDragEndEventHandler OnFingerDragEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's tap gesture recognizer OnTap event fires
|
||
/// </summary>
|
||
/// <seealso cref="TapGestureRecognizer.OnTap"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Tap"/>
|
||
public static /*event*/ FingerTapEventHandler OnFingerTap;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's double-tap gesture recognizer OnTap event fires
|
||
/// </summary>
|
||
/// <seealso cref="MultiTapGestureRecognizer.OnTap"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.DoubleTap"/>
|
||
public static /*event*/ FingerTapEventHandler OnFingerDoubleTap;
|
||
|
||
/// <summary>
|
||
/// Event fired when a finger's swipe gesture recognizer OnSwipe event fires
|
||
/// </summary>
|
||
/// <seealso cref="SwipeGestureRecognizer.OnSwipe"/>
|
||
/// <seealso cref="DefaultComponents.FingerComponents.Swipe"/>
|
||
public static /*event*/ FingerSwipeEventHandler OnFingerSwipe;
|
||
|
||
#endregion
|
||
|
||
#region Event-Raising Wrappers
|
||
|
||
internal static void RaiseOnFingerDown( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerDown != null )
|
||
OnFingerDown( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerUp( int fingerIndex, Vector2 fingerPos, float timeHeldDown )
|
||
{
|
||
if( OnFingerUp != null )
|
||
OnFingerUp( fingerIndex, fingerPos, timeHeldDown );
|
||
}
|
||
|
||
internal static void RaiseOnFingerStationaryBegin( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerStationaryBegin != null )
|
||
OnFingerStationaryBegin( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerStationary( int fingerIndex, Vector2 fingerPos, float elapsedTime )
|
||
{
|
||
if( OnFingerStationary != null )
|
||
OnFingerStationary( fingerIndex, fingerPos, elapsedTime );
|
||
}
|
||
|
||
internal static void RaiseOnFingerStationaryEnd( int fingerIndex, Vector2 fingerPos, float elapsedTime )
|
||
{
|
||
if( OnFingerStationaryEnd != null )
|
||
OnFingerStationaryEnd( fingerIndex, fingerPos, elapsedTime );
|
||
}
|
||
|
||
internal static void RaiseOnFingerMoveBegin( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
//FLogger.Log("RaiseOnFingerMoveBegin)", fingerIndex, fingerPos);
|
||
if( OnFingerMoveBegin != null )
|
||
OnFingerMoveBegin( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerMove( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerMove != null )
|
||
OnFingerMove( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerMoveEnd( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
//FLogger.Log("RaiseOnFingerMoveEnd)", fingerIndex, fingerPos);
|
||
if( OnFingerMoveEnd != null )
|
||
OnFingerMoveEnd( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerLongPress( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerLongPress != null )
|
||
OnFingerLongPress( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerLongPressing( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if(OnFingerLongPressing != null)
|
||
OnFingerLongPressing( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerDragBegin( int fingerIndex, Vector2 fingerPos, Vector2 startPos )
|
||
{
|
||
if( OnFingerDragBegin != null )
|
||
OnFingerDragBegin( fingerIndex, fingerPos, startPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerDragMove( int fingerIndex, Vector2 fingerPos, Vector2 delta )
|
||
{
|
||
if( OnFingerDragMove != null )
|
||
OnFingerDragMove( fingerIndex, fingerPos, delta );
|
||
}
|
||
|
||
internal static void RaiseOnFingerDragEnd( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerDragEnd != null )
|
||
OnFingerDragEnd( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerTap( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerTap != null )
|
||
OnFingerTap( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerDoubleTap( int fingerIndex, Vector2 fingerPos )
|
||
{
|
||
if( OnFingerDoubleTap != null )
|
||
OnFingerDoubleTap( fingerIndex, fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnFingerSwipe( int fingerIndex, Vector2 startPos, Vector2 endPos, SwipeDirection direction, float velocity )
|
||
{
|
||
if(OnFingerSwipe != null)
|
||
OnFingerSwipe( fingerIndex, startPos, endPos, direction, velocity );
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Global Gesture Events
|
||
|
||
//NOTE: events in this category are not global, in the sense that they take into account the current state of all the fingers. For instance,
|
||
// a single-finger gesture event such as OnTap will only fire if there is exactly one finger touching the screen (and tapping). If there are more touches,
|
||
// the gesture recognizer will fail, and the event will not be risen.
|
||
|
||
#region Delegates
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnLongPress event
|
||
/// </summary>
|
||
/// <param name="fingerPos">Screen position where the press occured</param>
|
||
public delegate void LongPressEventHandler( Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnTap and OnDoubleTap events
|
||
/// </summary>
|
||
/// <param name="fingerPos">Screen position where the tap occured</param>
|
||
public delegate void TapEventHandler( Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnSwipe event
|
||
/// </summary>
|
||
/// <param name="startPos">Initial finger position when the swipe gesture started</param>
|
||
/// <param name="direction">Direction of the swipe gesture</param>
|
||
/// <param name="velocity">How quickly the finger has moved (in screen pixels per second)</param>
|
||
public delegate void SwipeEventHandler( Vector2 startPos, FingerGestures.SwipeDirection direction, float velocity );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnDragBegin event
|
||
/// </summary>
|
||
/// <param name="fingerPos">The current finger position on the screen</param>
|
||
/// <param name="startPos">The initial screen position the gesture started from</param>
|
||
/// <remark>These two values can differ if the drag gesture recognizer's MoveThreshold is non-zero</remark>
|
||
public delegate void DragBeginEventHandler( Vector2 fingerPos, Vector2 startPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnDragMove event
|
||
/// </summary>
|
||
/// <param name="fingerPos">Current finger position on the screen</param>
|
||
/// <param name="delta">How much the finger has moved since the last update. This is the difference between the previous finger position and the new one.</param>
|
||
public delegate void DragMoveEventHandler( Vector2 fingerPos, Vector2 delta );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnDragEnd event
|
||
/// </summary>
|
||
/// <param name="fingerPos">Current position of the finger on the screen</param>
|
||
public delegate void DragEndEventHandler( Vector2 fingerPos );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnPinchBegin and OnPinchEnd events
|
||
/// </summary>
|
||
/// <param name="fingerPos1">First finger screen position</param>
|
||
/// <param name="fingerPos2">Second finger screen position</param>
|
||
public delegate void PinchEventHandler( Vector2 fingerPos1, Vector2 fingerPos2 );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnPinchMove event
|
||
/// </summary>
|
||
/// <param name="fingerPos1">First finger screen position</param>
|
||
/// <param name="fingerPos2">Second finger screen position</param>
|
||
/// <param name="delta">How much the distance between the two fingers has changed since the last update. A negative value means the two fingers got closer, while a positive value means they moved further apart</param>
|
||
public delegate void PinchMoveEventHandler( Vector2 fingerPos1, Vector2 fingerPos2, float delta );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnRotationBegin event
|
||
/// </summary>
|
||
/// <param name="fingerPos1">First finger screen position</param>
|
||
/// <param name="fingerPos2">Second finger screen position</param>
|
||
public delegate void RotationBeginEventHandler( Vector2 fingerPos1, Vector2 fingerPos2 );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnRotationMove event
|
||
/// </summary>
|
||
/// <param name="fingerPos1">First finger screen position</param>
|
||
/// <param name="fingerPos2">Second finger screen position</param>
|
||
/// <param name="rotationAngleDelta">Angle difference, in degrees, since the last update.</param>
|
||
public delegate void RotationMoveEventHandler( Vector2 fingerPos1, Vector2 fingerPos2, float rotationAngleDelta );
|
||
|
||
/// <summary>
|
||
/// Delegate for the OnRotationEnd event
|
||
/// </summary>
|
||
/// <param name="fingerPos1">First finger screen position</param>
|
||
/// <param name="fingerPos2">Second finger screen position</param>
|
||
/// <param name="totalRotationAngle">Total rotation performed during the gesture, in degrees</param>
|
||
public delegate void RotationEndEventHandler( Vector2 fingerPos1, Vector2 fingerPos2, float totalRotationAngle );
|
||
|
||
#endregion
|
||
|
||
#region Events
|
||
|
||
/// <summary>
|
||
/// Event fired when the default long-press gesture recognizer OnLongPress event fires
|
||
/// </summary>
|
||
/// <seealso cref="LongPressGestureRecognizer.OnLongPress"/>
|
||
/// <seealso cref="DefaultComponents.LongPress"/>
|
||
public static /*event*/ LongPressEventHandler OnLongPress;
|
||
|
||
public static /*event*/ LongPressEventHandler OnLongPressing;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default drag gesture recognizer's OnDragBegin event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragBegin"/>
|
||
/// <seealso cref="DefaultComponents.Drag"/>
|
||
public static /*event*/ DragBeginEventHandler OnDragBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default drag gesture recognizer's OnDragMove event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragMove"/>
|
||
/// <seealso cref="DefaultComponents.Drag"/>
|
||
public static /*event*/ DragMoveEventHandler OnDragMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default drag gesture recognizer's OnDragEnd event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragEnd"/>
|
||
/// <seealso cref="DefaultComponents.Drag"/>
|
||
public static /*event*/ DragEndEventHandler OnDragEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default tap gesture recognizer's OnTap event fires
|
||
/// </summary>
|
||
/// <seealso cref="TapGestureRecognizer.OnTap"/>
|
||
/// <seealso cref="DefaultComponents.Tap"/>
|
||
public static /*event*/ TapEventHandler OnTap;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default double-tap gesture recognizer's OnTap event fires
|
||
/// </summary>
|
||
/// <seealso cref="MultiTapGestureRecognizer.OnTap"/>
|
||
/// <seealso cref="DefaultComponents.DoubleTap"/>
|
||
public static /*event*/ TapEventHandler OnDoubleTap;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default swipe gesture recognizer's OnSwipe event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragEnd"/>
|
||
/// <seealso cref="DefaultComponents.Drag"/>
|
||
public static /*event*/ SwipeEventHandler OnSwipe;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnPinchBegin event fires
|
||
/// </summary>
|
||
/// <seealso cref="PinchGestureRecognizer.OnPinchBegin"/>
|
||
/// <seealso cref="DefaultComponents.Pinch"/>
|
||
public static /*event*/ PinchEventHandler OnPinchBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnPinchMove event fires
|
||
/// </summary>
|
||
/// <seealso cref="PinchGestureRecognizer.OnPinchMove"/>
|
||
/// <seealso cref="DefaultComponents.Pinch"/>
|
||
public static /*event*/ PinchMoveEventHandler OnPinchMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnPinchEnd event fires
|
||
/// <seealso cref="PinchGestureRecognizer.OnPinchEnd"/>
|
||
/// <seealso cref="DefaultComponents.Pinch"/>
|
||
/// </summary>
|
||
public static /*event*/ PinchEventHandler OnPinchEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnRotationBegin event fires
|
||
/// <seealso cref="RotationGestureRecognizer.OnRotationBegin"/>
|
||
/// <seealso cref="DefaultComponents.Rotation"/>
|
||
/// </summary>
|
||
public static /*event*/ RotationBeginEventHandler OnRotationBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnRotationMove event fires
|
||
/// <seealso cref="RotationGestureRecognizer.OnRotationMove"/>
|
||
/// <seealso cref="DefaultComponents.Rotation"/>
|
||
/// </summary>
|
||
public static /*event*/ RotationMoveEventHandler OnRotationMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default pinch gesture recognizer's OnRotationEnd event fires
|
||
/// <seealso cref="RotationGestureRecognizer.OnRotationEnd"/>
|
||
/// <seealso cref="DefaultComponents.Rotation"/>
|
||
/// </summary>
|
||
public static /*event*/ RotationEndEventHandler OnRotationEnd;
|
||
|
||
#region Two-Finger Versions
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger drag gesture recognizer's OnDragBegin event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragBegin"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerDrag"/>
|
||
public static event DragBeginEventHandler OnTwoFingerDragBegin;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger drag gesture recognizer's OnDragMove event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragMove"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerDrag"/>
|
||
public static event DragMoveEventHandler OnTwoFingerDragMove;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger drag gesture recognizer's OnDragEnd event fires
|
||
/// </summary>
|
||
/// <seealso cref="DragGestureRecognizer.OnDragEnd"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerDrag"/>
|
||
public static event DragEndEventHandler OnTwoFingerDragEnd;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger tap gesture recognizer's OnTap event fires
|
||
/// </summary>
|
||
/// <seealso cref="TapGestureRecognizer.OnTap"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerTap"/>
|
||
public static event TapEventHandler OnTwoFingerTap;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger tap gesture recognizer's OnSwipe event fires
|
||
/// </summary>
|
||
/// <seealso cref="SwipeGestureRecognizer.OnSwipe"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerSwipe"/>
|
||
public static event SwipeEventHandler OnTwoFingerSwipe;
|
||
|
||
/// <summary>
|
||
/// Event fired when the default two-finger long-press gesture recognizer's OnLongPress event fires
|
||
/// </summary>
|
||
/// <seealso cref="LongPressGestureRecognizer.OnLongPress"/>
|
||
/// <seealso cref="DefaultComponents.TwoFingerLongPress"/>
|
||
public static event LongPressEventHandler OnTwoFingerLongPress;
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Event-Raising Wrappers
|
||
|
||
internal static void RaiseOnLongPress( Vector2 fingerPos )
|
||
{
|
||
if( OnLongPress != null )
|
||
OnLongPress( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnLongPressing( Vector2 fingerPos )
|
||
{
|
||
if(OnLongPressing != null)
|
||
OnLongPressing( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnDragBegin( Vector2 fingerPos, Vector2 startPos )
|
||
{
|
||
if( OnDragBegin != null )
|
||
OnDragBegin( fingerPos, startPos );
|
||
}
|
||
|
||
internal static void RaiseOnDragMove( Vector2 fingerPos, Vector2 delta )
|
||
{
|
||
if( OnDragMove != null )
|
||
OnDragMove( fingerPos, delta );
|
||
}
|
||
|
||
internal static void RaiseOnDragEnd( Vector2 fingerPos )
|
||
{
|
||
if( OnDragEnd != null )
|
||
OnDragEnd( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnTap( Vector2 fingerPos )
|
||
{
|
||
if( OnTap != null )
|
||
OnTap( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnDoubleTap( Vector2 fingerPos )
|
||
{
|
||
if( OnDoubleTap != null )
|
||
OnDoubleTap( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnSwipe( Vector2 startPos, SwipeDirection direction, float velocity )
|
||
{
|
||
if( OnSwipe != null )
|
||
OnSwipe( startPos, direction, velocity );
|
||
}
|
||
|
||
internal static void RaiseOnPinchBegin( Vector2 fingerPos1, Vector2 fingerPos2 )
|
||
{
|
||
if( OnPinchBegin != null )
|
||
OnPinchBegin( fingerPos1, fingerPos2 );
|
||
}
|
||
|
||
internal static void RaiseOnPinchMove( Vector2 fingerPos1, Vector2 fingerPos2, float delta )
|
||
{
|
||
if( OnPinchMove != null )
|
||
OnPinchMove( fingerPos1, fingerPos2, delta );
|
||
}
|
||
|
||
internal static void RaiseOnPinchEnd( Vector2 fingerPos1, Vector2 fingerPos2 )
|
||
{
|
||
if( OnPinchEnd != null )
|
||
OnPinchEnd( fingerPos1, fingerPos2 );
|
||
}
|
||
|
||
internal static void RaiseOnRotationBegin( Vector2 fingerPos1, Vector2 fingerPos2 )
|
||
{
|
||
if( OnRotationBegin != null )
|
||
OnRotationBegin( fingerPos1, fingerPos2 );
|
||
}
|
||
|
||
internal static void RaiseOnRotationMove( Vector2 fingerPos1, Vector2 fingerPos2, float rotationAngleDelta )
|
||
{
|
||
if( OnRotationMove != null )
|
||
OnRotationMove( fingerPos1, fingerPos2, rotationAngleDelta );
|
||
}
|
||
|
||
internal static void RaiseOnRotationEnd( Vector2 fingerPos1, Vector2 fingerPos2, float totalRotationAngle )
|
||
{
|
||
if( OnRotationEnd != null )
|
||
OnRotationEnd( fingerPos1, fingerPos2, totalRotationAngle );
|
||
}
|
||
|
||
#region Two Finger Versions
|
||
|
||
internal static void RaiseOnTwoFingerLongPress( Vector2 fingerPos )
|
||
{
|
||
if( OnTwoFingerLongPress != null )
|
||
OnTwoFingerLongPress( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnTwoFingerDragBegin( Vector2 fingerPos, Vector2 startPos )
|
||
{
|
||
if( OnTwoFingerDragBegin != null )
|
||
OnTwoFingerDragBegin( fingerPos, startPos );
|
||
}
|
||
|
||
internal static void RaiseOnTwoFingerDragMove( Vector2 fingerPos, Vector2 delta )
|
||
{
|
||
if( OnTwoFingerDragMove != null )
|
||
OnTwoFingerDragMove( fingerPos, delta );
|
||
}
|
||
|
||
internal static void RaiseOnTwoFingerDragEnd( Vector2 fingerPos )
|
||
{
|
||
if( OnTwoFingerDragEnd != null )
|
||
OnTwoFingerDragEnd( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnTwoFingerTap( Vector2 fingerPos )
|
||
{
|
||
if( OnTwoFingerTap != null )
|
||
OnTwoFingerTap( fingerPos );
|
||
}
|
||
|
||
internal static void RaiseOnTwoFingerSwipe( Vector2 startPos, SwipeDirection direction, float velocity )
|
||
{
|
||
if( OnTwoFingerSwipe != null )
|
||
OnTwoFingerSwipe( startPos, direction, velocity );
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// Access to the FingerGestures singleton instance
|
||
/// </summary>
|
||
public static FingerGestures Instance
|
||
{
|
||
get { return FingerGestures.instance; }
|
||
}
|
||
|
||
#region Finger
|
||
|
||
/// <summary>
|
||
/// Finger Phase
|
||
/// </summary>
|
||
public enum FingerPhase
|
||
{
|
||
None,
|
||
|
||
/// <summary>
|
||
/// The finger just touched the screen
|
||
/// </summary>
|
||
Began,
|
||
|
||
/// <summary>
|
||
/// The finger just moved
|
||
/// </summary>
|
||
Moved,
|
||
|
||
/// <summary>
|
||
/// The finger is stationary
|
||
/// </summary>
|
||
Stationary,
|
||
|
||
/// <summary>
|
||
/// The finger was lifted off the screen
|
||
/// </summary>
|
||
Ended,
|
||
}
|
||
|
||
/// <summary>
|
||
/// Finger
|
||
///
|
||
/// This provides an abstraction for a finger that can touch and move around the screen.
|
||
/// As opposed to Unity's Touch object, a Finger exists independently of whether it is
|
||
/// currently touching the screen or not
|
||
/// </summary>
|
||
public class Finger
|
||
{
|
||
#region Properties
|
||
|
||
/// <summary>
|
||
/// Unique identifier for this finger.
|
||
/// For touch screen gestures, this corresponds to Touch.index, and the button index for mouse gestures.
|
||
/// </summary>
|
||
public int Index
|
||
{
|
||
get { return index; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Current phase
|
||
/// </summary>
|
||
public FingerPhase Phase
|
||
{
|
||
get { return phase; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return true if the finger is currently down
|
||
/// </summary>
|
||
public bool IsDown
|
||
{
|
||
get { return down; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return true if the finger was down during the previous update/frame
|
||
/// </summary>
|
||
public bool WasDown
|
||
{
|
||
get { return wasDown; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the time of first screen contact
|
||
/// </summary>
|
||
public float StarTime
|
||
{
|
||
get { return startTime; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the position of first screen contact
|
||
/// </summary>
|
||
public Vector2 StartPosition
|
||
{
|
||
get { return startPos; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the current position
|
||
/// </summary>
|
||
public Vector2 Position
|
||
{
|
||
get { return pos; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the position during the previous frame
|
||
/// </summary>
|
||
public Vector2 PreviousPosition
|
||
{
|
||
get { return prevPos; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the difference between previous and current position
|
||
/// </summary>
|
||
public Vector2 DeltaPosition
|
||
{
|
||
get { return deltaPos; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the distance traveled from initial position
|
||
/// </summary>
|
||
public float DistanceFromStart
|
||
{
|
||
get { return distFromStart; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return true if this finger is currently being filtered out via the global touch filter
|
||
/// </summary>
|
||
public bool Filtered
|
||
{
|
||
get { return filteredOut; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Events
|
||
|
||
/// <summary>
|
||
/// Delegate for OnDown and OnUp events
|
||
/// </summary>
|
||
/// <param name="finger">the finger firing the event</param>
|
||
public delegate void FingerEventDelegate( Finger finger );
|
||
|
||
/// <summary>
|
||
/// Event fired on the first frame the finger is down
|
||
/// </summary>
|
||
public event FingerEventDelegate OnDown;
|
||
|
||
/// <summary>
|
||
/// Event fired when the finger, previously down, has just been released. e.g. this would be the equivalent of a "mouse up" button event.
|
||
/// </summary>
|
||
public event FingerEventDelegate OnUp;
|
||
|
||
#endregion
|
||
|
||
#region Internal
|
||
|
||
int index = 0;
|
||
bool wasDown = false;
|
||
bool down = false;
|
||
bool filteredOut = true; // is this finger being filtered out?
|
||
float startTime = 0;
|
||
FingerPhase phase = FingerPhase.None;
|
||
Vector2 startPos = Vector2.zero;
|
||
Vector2 pos = Vector2.zero;
|
||
Vector2 prevPos = Vector2.zero;
|
||
Vector2 deltaPos = Vector2.zero;
|
||
float distFromStart = 0;
|
||
|
||
public Finger( int index )
|
||
{
|
||
this.index = index;
|
||
}
|
||
|
||
public override string ToString()
|
||
{
|
||
return "Finger" + index;
|
||
}
|
||
|
||
internal void Update( FingerPhase newPhase, Vector2 newPos )
|
||
{
|
||
if( filteredOut )
|
||
{
|
||
// stop ignoring this touch when the finger is no longer touching the screen
|
||
if( newPhase == FingerPhase.Ended || newPhase == FingerPhase.None )
|
||
filteredOut = false;
|
||
|
||
newPhase = FingerPhase.None;
|
||
}
|
||
|
||
// validate phase transitions
|
||
if( phase != newPhase )
|
||
{
|
||
// In low framerate situations, it is possible to miss some input updates and thus
|
||
// skip the "Ended" phase
|
||
if( newPhase == FingerPhase.None && phase != FingerPhase.Ended )
|
||
{
|
||
UnityEngine.Debug.LogWarning( "Correcting bad FingerPhase transition (FingerPhase.Ended skipped)" );
|
||
Update( FingerPhase.Ended, PreviousPosition );
|
||
return;
|
||
}
|
||
|
||
// cannot get a Moved or Stationary phase without being down first
|
||
if( !down && ( newPhase == FingerPhase.Moved || newPhase == FingerPhase.Stationary ) )
|
||
{
|
||
UnityEngine.Debug.LogWarning( "Correcting bad FingerPhase transition (FingerPhase.Began skipped)" );
|
||
Update( FingerPhase.Began, newPos );
|
||
return;
|
||
}
|
||
|
||
if( ( down && newPhase == FingerPhase.Began ) || ( !down && newPhase == FingerPhase.Ended ) )
|
||
{
|
||
UnityEngine.Debug.LogWarning( "Invalid state FingerPhase transition from " + phase + " to " + newPhase + " - Skipping." );
|
||
return;
|
||
}
|
||
}
|
||
else // same phase as before
|
||
{
|
||
if( newPhase == FingerPhase.Began || newPhase == FingerPhase.Ended )
|
||
{
|
||
UnityEngine.Debug.LogWarning( "Duplicated FingerPhase." + newPhase.ToString() + " - skipping." );
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Apply global touch filter
|
||
if( newPhase == FingerPhase.Began && !FingerGestures.instance.ShouldProcessTouch( index, newPos ) )
|
||
{
|
||
filteredOut = true;
|
||
newPhase = FingerPhase.None;
|
||
}
|
||
|
||
if( newPhase != FingerPhase.None )
|
||
{
|
||
if( newPhase == FingerPhase.Ended )
|
||
{
|
||
// release
|
||
down = false;
|
||
}
|
||
else
|
||
{
|
||
if( newPhase == FingerPhase.Began )
|
||
{
|
||
// activate
|
||
down = true;
|
||
startPos = newPos;
|
||
prevPos = newPos;
|
||
startTime = Time.time;
|
||
}
|
||
|
||
prevPos = pos;
|
||
pos = newPos;
|
||
deltaPos = pos - prevPos;
|
||
distFromStart = Vector3.Distance( startPos, pos );
|
||
}
|
||
}
|
||
|
||
phase = newPhase;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PostUpdate
|
||
/// We use PostUpdate() to raise the OnDown/OnUp events after all the fingers have been properly updated
|
||
/// </summary>
|
||
internal void PostUpdate()
|
||
{
|
||
if( wasDown != down )
|
||
{
|
||
if( down )
|
||
{
|
||
if( OnDown != null )
|
||
OnDown( this );
|
||
}
|
||
else
|
||
{
|
||
if( OnUp != null )
|
||
OnUp( this );
|
||
}
|
||
}
|
||
|
||
wasDown = down;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a finger by its index
|
||
/// </summary>
|
||
public static Finger GetFinger( int index )
|
||
{
|
||
return instance.fingers[index];
|
||
}
|
||
|
||
/// <summary>
|
||
/// List of fingers currently touching the screen
|
||
/// </summary>
|
||
public static IFingerList Touches
|
||
{
|
||
get
|
||
{
|
||
if( instance == null )
|
||
UnityEngine.Debug.LogError( "Null FG instance!" );
|
||
|
||
if( instance.touches == null )
|
||
UnityEngine.Debug.LogError( "Null instance.touches!" );
|
||
|
||
return instance.touches;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Engine Callbacks
|
||
|
||
|
||
|
||
|
||
protected virtual void Awake()
|
||
{
|
||
|
||
}
|
||
|
||
// this is called after Awake() OR after the script is recompiled (Recompile > Disable > Enable)
|
||
protected virtual void OnEnable()
|
||
{
|
||
//Debug.Log("FingerGestures:OnEnable:" + name);
|
||
if( instance == null )
|
||
{
|
||
instance = this;
|
||
InitFingers( MaxFingers );
|
||
}
|
||
else if( instance != this )
|
||
{
|
||
//UnityEngine.Debug.LogWarning( "There is already an instance of FingerGestures created (" + instance.name + "). Destroying new one." );
|
||
Destroy( this.gameObject );
|
||
return;
|
||
}
|
||
}
|
||
|
||
protected virtual void Start()
|
||
{
|
||
Debug.Log("FingerGestures:Start:" + name);
|
||
}
|
||
|
||
protected virtual void OnDisable()
|
||
{
|
||
Debug.Log("FingerGestures:OnDisable:" + name);
|
||
}
|
||
|
||
public delegate void FingersUpdatedEventDelegate();
|
||
public static event FingersUpdatedEventDelegate OnFingersUpdated;
|
||
|
||
protected virtual void Update()
|
||
{
|
||
UpdateFingers();
|
||
|
||
if( OnFingersUpdated != null )
|
||
OnFingersUpdated();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Overridable methods
|
||
|
||
/// <summary>
|
||
/// Maximum number of simultaneous fingers supported
|
||
/// </summary>
|
||
public abstract int MaxFingers { get; }
|
||
|
||
/// <summary>
|
||
/// Return the new phase of the finger for this frame
|
||
/// </summary>
|
||
protected abstract FingerPhase GetPhase( Finger finger );
|
||
|
||
/// <summary>
|
||
/// Return the new position of the finger on the screen for this frame
|
||
/// </summary>
|
||
protected abstract Vector2 GetPosition( Finger finger );
|
||
|
||
#endregion
|
||
|
||
#region Internal
|
||
|
||
// access to the singleton
|
||
static FingerGestures instance;
|
||
|
||
#region Fingers Management
|
||
|
||
Finger[] fingers;
|
||
FingerList touches;
|
||
|
||
void InitFingers( int count )
|
||
{
|
||
// pre-allocate a touch data entry for each finger
|
||
fingers = new Finger[count];
|
||
|
||
for( int i = 0; i < count; ++i )
|
||
fingers[i] = new Finger( i );
|
||
|
||
touches = new FingerList();
|
||
|
||
InitDefaultComponents();
|
||
}
|
||
|
||
void UpdateFingers()
|
||
{
|
||
touches.Clear();
|
||
|
||
// update all fingers
|
||
|
||
for (int i = 0; i < fingers.Length; i++ )
|
||
{
|
||
Vector2 pos = Vector2.zero;
|
||
FingerPhase phase = GetPhase(fingers[i]);
|
||
|
||
if (phase != FingerPhase.None)
|
||
pos = GetPosition(fingers[i]);
|
||
|
||
fingers[i].Update(phase, pos);
|
||
|
||
if (fingers[i].IsDown)
|
||
touches.Add(fingers[i]);
|
||
}
|
||
|
||
// post-update
|
||
for (int i = 0; i < fingers.Length; i++ )
|
||
{
|
||
fingers[i].PostUpdate();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Global Input Filter
|
||
|
||
/// <summary>
|
||
/// Return tru
|
||
/// </summary>
|
||
/// <param name="fingerIndex">The index of the finger that just touched the screen</param>
|
||
/// <param name="position">The new finger position if the input is let through</param>
|
||
/// <returns>True to let the touch go through, or false to block it</returns>
|
||
public delegate bool GlobalTouchFilterDelegate( int fingerIndex, Vector2 position );
|
||
GlobalTouchFilterDelegate globalTouchFilterFunc;
|
||
|
||
/// <summary>
|
||
/// Can specify a method to selectively prevent new touches from being processed until they are released.
|
||
/// This can be useful to globally deny gesture events from being fired when above a region of the screen,
|
||
/// or when the input has been consumed by another input system
|
||
/// </summary>
|
||
public static GlobalTouchFilterDelegate GlobalTouchFilter
|
||
{
|
||
get { return instance.globalTouchFilterFunc; }
|
||
set { instance.globalTouchFilterFunc = value; }
|
||
}
|
||
|
||
protected bool ShouldProcessTouch( int fingerIndex, Vector2 position )
|
||
{
|
||
if( globalTouchFilterFunc != null )
|
||
return globalTouchFilterFunc( fingerIndex, position );
|
||
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Default Per-Finger & Global Gesture Recognizers
|
||
|
||
/// <summary>
|
||
/// List of the default gesture recognizer prefabs to allocate during initialization
|
||
/// </summary>
|
||
public FingerGesturesPrefabs defaultPrefabs; // prefabs
|
||
|
||
Transform globalComponentNode;
|
||
Transform[] fingerComponentNodes;
|
||
|
||
T CreateDefaultComponent<T>( T prefab, Transform parent ) where T : FGComponent
|
||
{
|
||
T comp = Instantiate( prefab ) as T;
|
||
comp.gameObject.name = prefab.name;
|
||
comp.transform.parent = parent;
|
||
return comp;
|
||
}
|
||
|
||
T CreateDefaultGlobalComponent<T>( T prefab ) where T : FGComponent
|
||
{
|
||
return CreateDefaultComponent<T>( prefab, globalComponentNode );
|
||
}
|
||
|
||
T CreateDefaultFingerComponent<T>( Finger finger, T prefab ) where T : FGComponent
|
||
{
|
||
return CreateDefaultComponent<T>( prefab, fingerComponentNodes[finger.Index] );
|
||
}
|
||
|
||
[System.Serializable]
|
||
public class DefaultComponentCreationFlags
|
||
{
|
||
[System.Serializable]
|
||
public class PerFinger
|
||
{
|
||
public bool enabled = true;
|
||
|
||
public bool touch = true; // FingerDown & FingerUp
|
||
public bool motion = true; // FingerMove & FingerStationary
|
||
public bool longPress = true;
|
||
public bool drag = true;
|
||
public bool swipe = true;
|
||
public bool tap = true;
|
||
public bool doubleTap = true;
|
||
}
|
||
|
||
[System.Serializable]
|
||
public class GlobalGestures
|
||
{
|
||
public bool enabled = true;
|
||
|
||
public bool longPress = true;
|
||
public bool drag = true;
|
||
public bool swipe = true;
|
||
public bool tap = true;
|
||
public bool doubleTap = true;
|
||
public bool pinch = true;
|
||
public bool rotation = true;
|
||
public bool twoFingerLongPress = true;
|
||
public bool twoFingerDrag = true;
|
||
public bool twoFingerSwipe = true;
|
||
public bool twoFingerTap = true;
|
||
}
|
||
|
||
public PerFinger perFinger;
|
||
public GlobalGestures globalGestures;
|
||
}
|
||
|
||
/// <summary>
|
||
/// This holds a reference to all the default components/gesture recognizers automatically created at initialization
|
||
/// </summary>
|
||
public class DefaultComponents
|
||
{
|
||
public DefaultComponents( int fingerCount )
|
||
{
|
||
fingers = new FingerComponents[fingerCount];
|
||
for( int i = 0; i < fingers.Length; ++i )
|
||
fingers[i] = new FingerComponents();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Per-Finger components
|
||
/// </summary>
|
||
public class FingerComponents
|
||
{
|
||
public FingerMotionDetector Motion;
|
||
public LongPressGestureRecognizer LongPress;
|
||
public LongPressingGestureRecognizer LongPressing;
|
||
public DragGestureRecognizer Drag;
|
||
public TapGestureRecognizer Tap;
|
||
public MultiTapGestureRecognizer DoubleTap;
|
||
public SwipeGestureRecognizer Swipe;
|
||
}
|
||
|
||
FingerComponents[] fingers;
|
||
public FingerComponents[] Fingers
|
||
{
|
||
get { return fingers; }
|
||
}
|
||
|
||
// global components
|
||
public LongPressGestureRecognizer LongPress;
|
||
public LongPressingGestureRecognizer LongPressing;
|
||
public DragGestureRecognizer Drag;
|
||
public TapGestureRecognizer Tap;
|
||
public MultiTapGestureRecognizer DoubleTap;
|
||
public SwipeGestureRecognizer Swipe;
|
||
public PinchGestureRecognizer Pinch;
|
||
public RotationGestureRecognizer Rotation;
|
||
public LongPressGestureRecognizer TwoFingerLongPress;
|
||
public DragGestureRecognizer TwoFingerDrag;
|
||
public TapGestureRecognizer TwoFingerTap;
|
||
public SwipeGestureRecognizer TwoFingerSwipe;
|
||
}
|
||
|
||
/// <summary>
|
||
/// List of flags indicating whether or not a default recognizer should be created for a specific gesture.
|
||
/// This can be used to turn off the gestures you do not care about and thus optimize performances a little bit further
|
||
/// </summary>
|
||
public DefaultComponentCreationFlags defaultCompFlags;
|
||
|
||
DefaultComponents defaultComponents;
|
||
|
||
/// <summary>
|
||
/// Get access to the default components / gesture recognizers
|
||
/// </summary>
|
||
public static DefaultComponents Defaults
|
||
{
|
||
get { return instance.defaultComponents; }
|
||
}
|
||
|
||
Transform CreateNode( string name, Transform parent )
|
||
{
|
||
GameObject go = new GameObject( name );
|
||
go.transform.parent = parent;
|
||
return go.transform;
|
||
}
|
||
|
||
void InitDefaultComponents()
|
||
{
|
||
int fingerCount = fingers.Length;
|
||
|
||
if( globalComponentNode )
|
||
Destroy( globalComponentNode.gameObject );
|
||
|
||
if( fingerComponentNodes != null )
|
||
{
|
||
for (int i = 0; i < fingerComponentNodes.Length; i++)
|
||
{
|
||
Destroy(fingerComponentNodes[i].gameObject);
|
||
}
|
||
}
|
||
|
||
globalComponentNode = CreateNode( "Global Components", this.transform );
|
||
|
||
fingerComponentNodes = new Transform[fingerCount];
|
||
for( int i = 0; i < fingerComponentNodes.Length; ++i )
|
||
fingerComponentNodes[i] = CreateNode( "Finger" + i, this.transform );
|
||
|
||
defaultComponents = new DefaultComponents( fingerCount );
|
||
|
||
if( defaultCompFlags.globalGestures.enabled )
|
||
InitGlobalGestures();
|
||
|
||
if( defaultCompFlags.perFinger.enabled )
|
||
{
|
||
for (int i = 0; i < fingers.Length; i++)
|
||
{
|
||
InitDefaultComponents(fingers[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
void InitGlobalGestures()
|
||
{
|
||
// default long press gesture
|
||
if( defaultCompFlags.globalGestures.longPress )
|
||
{
|
||
{
|
||
LongPressGestureRecognizer longPress = CreateDefaultGlobalComponent( defaultPrefabs.longPress );
|
||
longPress.OnLongPress += delegate( LongPressGestureRecognizer rec ) { RaiseOnLongPress( rec.Position ); };
|
||
defaultComponents.LongPress = longPress;
|
||
}
|
||
|
||
{
|
||
LongPressingGestureRecognizer longPressing = CreateDefaultGlobalComponent( defaultPrefabs.longPressing );
|
||
longPressing.OnLongPressing += delegate( LongPressingGestureRecognizer rec ) { RaiseOnLongPressing( rec.Position ); };
|
||
defaultComponents.LongPressing = longPressing;
|
||
}
|
||
}
|
||
|
||
// default long press gesture
|
||
if( defaultCompFlags.globalGestures.twoFingerLongPress )
|
||
{
|
||
LongPressGestureRecognizer longPress = CreateDefaultGlobalComponent( defaultPrefabs.twoFingerLongPress );
|
||
longPress.RequiredFingerCount = 2;
|
||
longPress.OnLongPress += delegate( LongPressGestureRecognizer rec ) { RaiseOnTwoFingerLongPress( rec.Position ); };
|
||
defaultComponents.TwoFingerLongPress = longPress;
|
||
}
|
||
|
||
// default drag detector
|
||
if( defaultCompFlags.globalGestures.drag )
|
||
{
|
||
DragGestureRecognizer drag = CreateDefaultGlobalComponent( defaultPrefabs.drag );
|
||
drag.OnDragBegin += delegate( DragGestureRecognizer rec ) { RaiseOnDragBegin( rec.Position, rec.StartPosition ); };
|
||
drag.OnDragMove += delegate( DragGestureRecognizer rec ) { RaiseOnDragMove( rec.Position, rec.MoveDelta ); };
|
||
drag.OnDragEnd += delegate( DragGestureRecognizer rec ) { RaiseOnDragEnd( rec.Position ); };
|
||
defaultComponents.Drag = drag;
|
||
}
|
||
|
||
// default two-finger drag detector
|
||
if( defaultCompFlags.globalGestures.twoFingerDrag )
|
||
{
|
||
DragGestureRecognizer drag = CreateDefaultGlobalComponent( defaultPrefabs.twoFingerDrag );
|
||
drag.RequiredFingerCount = 2;
|
||
drag.OnDragBegin += delegate( DragGestureRecognizer rec ) { RaiseOnTwoFingerDragBegin( rec.Position, rec.StartPosition ); };
|
||
drag.OnDragMove += delegate( DragGestureRecognizer rec ) { RaiseOnTwoFingerDragMove( rec.Position, rec.MoveDelta ); };
|
||
drag.OnDragEnd += delegate( DragGestureRecognizer rec ) { RaiseOnTwoFingerDragEnd( rec.Position ); };
|
||
defaultComponents.TwoFingerDrag = drag;
|
||
}
|
||
|
||
// default swipe detector
|
||
if( defaultCompFlags.globalGestures.swipe )
|
||
{
|
||
SwipeGestureRecognizer swipe = CreateDefaultGlobalComponent( defaultPrefabs.swipe );
|
||
swipe.OnSwipe += delegate( SwipeGestureRecognizer rec ) { RaiseOnSwipe( rec.StartPosition, rec.Direction, rec.Velocity ); };
|
||
defaultComponents.Swipe = swipe;
|
||
}
|
||
|
||
// default two-finger swipe detector
|
||
if( defaultCompFlags.globalGestures.twoFingerSwipe )
|
||
{
|
||
SwipeGestureRecognizer swipe = CreateDefaultGlobalComponent( defaultPrefabs.twoFingerSwipe );
|
||
swipe.RequiredFingerCount = 2;
|
||
swipe.OnSwipe += delegate( SwipeGestureRecognizer rec ) { RaiseOnTwoFingerSwipe( rec.StartPosition, rec.Direction, rec.Velocity ); };
|
||
defaultComponents.TwoFingerSwipe = swipe;
|
||
}
|
||
|
||
// default tap detector
|
||
if( defaultCompFlags.globalGestures.tap )
|
||
{
|
||
TapGestureRecognizer tap = CreateDefaultGlobalComponent( defaultPrefabs.tap );
|
||
tap.OnTap += delegate( TapGestureRecognizer rec ) { RaiseOnTap( rec.Position ); };
|
||
defaultComponents.Tap = tap;
|
||
}
|
||
|
||
// default double tap detector
|
||
if( defaultCompFlags.globalGestures.doubleTap )
|
||
{
|
||
MultiTapGestureRecognizer doubleTap = CreateDefaultGlobalComponent( defaultPrefabs.doubleTap );
|
||
doubleTap.OnTap += delegate( MultiTapGestureRecognizer rec ) { RaiseOnDoubleTap( rec.Position ); };
|
||
defaultComponents.DoubleTap = doubleTap;
|
||
}
|
||
|
||
// default two-finger tap detector
|
||
if( defaultCompFlags.globalGestures.twoFingerTap )
|
||
{
|
||
TapGestureRecognizer tap = CreateDefaultGlobalComponent( defaultPrefabs.twoFingerTap );
|
||
tap.RequiredFingerCount = 2;
|
||
tap.OnTap += delegate( TapGestureRecognizer rec ) { RaiseOnTwoFingerTap( rec.Position ); };
|
||
defaultComponents.TwoFingerTap = tap;
|
||
}
|
||
|
||
// default pinch recognizer
|
||
if( defaultCompFlags.globalGestures.pinch )
|
||
{
|
||
PinchGestureRecognizer pinch = CreateDefaultGlobalComponent( defaultPrefabs.pinch );
|
||
pinch.OnPinchBegin += delegate( PinchGestureRecognizer rec ) { RaiseOnPinchBegin( rec.GetPosition( 0 ), rec.GetPosition( 1 ) ); };
|
||
pinch.OnPinchMove += delegate( PinchGestureRecognizer rec ) { RaiseOnPinchMove( rec.GetPosition( 0 ), rec.GetPosition( 1 ), rec.Delta ); };
|
||
pinch.OnPinchEnd += delegate( PinchGestureRecognizer rec ) { RaiseOnPinchEnd( rec.GetPosition( 0 ), rec.GetPosition( 1 ) ); }; ;
|
||
defaultComponents.Pinch = pinch;
|
||
}
|
||
|
||
// default rotation recognizer
|
||
if( defaultCompFlags.globalGestures.rotation )
|
||
{
|
||
RotationGestureRecognizer rotation = CreateDefaultGlobalComponent( defaultPrefabs.rotation );
|
||
rotation.OnRotationBegin += delegate( RotationGestureRecognizer rec ) { RaiseOnRotationBegin( rec.GetPosition( 0 ), rec.GetPosition( 1 ) ); };
|
||
rotation.OnRotationMove += delegate( RotationGestureRecognizer rec ) { RaiseOnRotationMove( rec.GetPosition( 0 ), rec.GetPosition( 1 ), rec.RotationDelta ); };
|
||
rotation.OnRotationEnd += delegate( RotationGestureRecognizer rec ) { RaiseOnRotationEnd( rec.GetPosition( 0 ), rec.GetPosition( 1 ), rec.TotalRotation ); };
|
||
defaultComponents.Rotation = rotation;
|
||
}
|
||
}
|
||
|
||
void InitDefaultComponents( Finger finger )
|
||
{
|
||
ITouchFilter touchFilter = new SingleFingerFilter( finger );
|
||
DefaultComponents.FingerComponents defaultFingerComponents = defaultComponents.Fingers[finger.Index];
|
||
|
||
// touch down & up events
|
||
if( defaultCompFlags.perFinger.touch )
|
||
{
|
||
finger.OnDown += PerFinger_OnDown;
|
||
finger.OnUp += PerFinger_OnUp;
|
||
}
|
||
|
||
// setup a default motion detector using the "global" moveThreshold specified on the FingerGestures object
|
||
// this is for backward compatibility with previous 1.X versions
|
||
if( defaultCompFlags.perFinger.motion )
|
||
{
|
||
FingerMotionDetector motion = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerMotion );
|
||
motion.Finger = finger;
|
||
motion.OnMoveBegin += PerFinger_OnMoveBegin;
|
||
motion.OnMove += PerFinger_OnMove;
|
||
motion.OnMoveEnd += PerFinger_OnMoveEnd;
|
||
motion.OnStationaryBegin += PerFinger_OnStationaryBegin;
|
||
motion.OnStationary += PerFinger_OnStationary;
|
||
motion.OnStationaryEnd += PerFinger_OnStationaryEnd;
|
||
defaultFingerComponents.Motion = motion;
|
||
}
|
||
|
||
// default long press gesture
|
||
if( defaultCompFlags.perFinger.longPress )
|
||
{
|
||
{
|
||
LongPressGestureRecognizer longPress = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerLongPress );
|
||
longPress.TouchFilter = touchFilter;
|
||
longPress.OnLongPress += PerFinger_OnLongPress;
|
||
defaultFingerComponents.LongPress = longPress;
|
||
}
|
||
{
|
||
LongPressingGestureRecognizer longPressing = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerLongPressing );
|
||
longPressing.TouchFilter = touchFilter;
|
||
longPressing.OnLongPressing += PerFinger_OnLongPressing;
|
||
defaultFingerComponents.LongPressing = longPressing;
|
||
}
|
||
|
||
}
|
||
|
||
// setup default drag detector
|
||
if( defaultCompFlags.perFinger.drag )
|
||
{
|
||
DragGestureRecognizer drag = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerDrag );
|
||
drag.TouchFilter = touchFilter;
|
||
drag.OnDragBegin += PerFinger_OnDragBegin;
|
||
drag.OnDragMove += PerFinger_OnDragMove;
|
||
drag.OnDragEnd += PerFinger_OnDragEnd;
|
||
defaultFingerComponents.Drag = drag;
|
||
}
|
||
|
||
// setup default swipe detector
|
||
if( defaultCompFlags.perFinger.swipe )
|
||
{
|
||
SwipeGestureRecognizer swipe = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerSwipe );
|
||
swipe.TouchFilter = touchFilter;
|
||
swipe.OnSwipe += PerFinger_OnSwipe;
|
||
defaultFingerComponents.Swipe = swipe;
|
||
}
|
||
|
||
// setup default tap detector
|
||
if( defaultCompFlags.perFinger.tap )
|
||
{
|
||
TapGestureRecognizer tap = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerTap );
|
||
tap.TouchFilter = touchFilter;
|
||
tap.OnTap += PerFinger_OnTap;
|
||
defaultFingerComponents.Tap = tap;
|
||
}
|
||
|
||
// setup default double tap detector
|
||
if( defaultCompFlags.perFinger.doubleTap )
|
||
{
|
||
MultiTapGestureRecognizer doubleTap = CreateDefaultFingerComponent( finger, defaultPrefabs.fingerDoubleTap );
|
||
doubleTap.TouchFilter = touchFilter;
|
||
doubleTap.OnTap += PerFinger_OnDoubleTap;
|
||
defaultFingerComponents.DoubleTap = doubleTap;
|
||
}
|
||
}
|
||
|
||
static Finger GetFingerFromTouchFilter( GestureRecognizer recognizer )
|
||
{
|
||
SingleFingerFilter filter = recognizer.TouchFilter as SingleFingerFilter;
|
||
|
||
if( filter != null )
|
||
return filter.Finger;
|
||
|
||
return null;
|
||
}
|
||
|
||
#region Per-Finger Gestures Callbacks
|
||
|
||
void PerFinger_OnDown( Finger source )
|
||
{
|
||
RaiseOnFingerDown( source.Index, source.Position );
|
||
}
|
||
|
||
void PerFinger_OnUp( Finger source )
|
||
{
|
||
RaiseOnFingerUp( source.Index, source.Position, Time.time - source.StarTime );
|
||
}
|
||
|
||
void PerFinger_OnStationaryBegin( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerStationaryBegin( source.Finger.Index, source.AnchorPos );
|
||
}
|
||
|
||
void PerFinger_OnStationary( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerStationary( source.Finger.Index, source.Finger.Position, source.ElapsedStationaryTime );
|
||
}
|
||
|
||
void PerFinger_OnStationaryEnd( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerStationaryEnd( source.Finger.Index, source.Finger.PreviousPosition, source.ElapsedStationaryTime );
|
||
}
|
||
|
||
void PerFinger_OnMoveBegin( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerMoveBegin( source.Finger.Index, source.AnchorPos );
|
||
}
|
||
|
||
void PerFinger_OnMove( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerMove( source.Finger.Index, source.Finger.Position );
|
||
}
|
||
|
||
void PerFinger_OnMoveEnd( FingerMotionDetector source )
|
||
{
|
||
RaiseOnFingerMoveEnd( source.Finger.Index, source.Finger.Position );
|
||
}
|
||
|
||
void PerFinger_OnDragBegin( DragGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerDragBegin( finger.Index, source.Position, source.StartPosition );
|
||
}
|
||
|
||
void PerFinger_OnDragMove( DragGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerDragMove( finger.Index, source.Position, source.MoveDelta );
|
||
}
|
||
|
||
void PerFinger_OnDragEnd( DragGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerDragEnd( finger.Index, source.Position );
|
||
}
|
||
|
||
void PerFinger_OnLongPress( LongPressGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerLongPress( finger.Index, source.Position );
|
||
}
|
||
|
||
void PerFinger_OnLongPressing( LongPressingGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerLongPressing( finger.Index, source.Position );
|
||
}
|
||
|
||
void PerFinger_OnSwipe( SwipeGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerSwipe( finger.Index, source.StartPosition, source.Position, source.Direction, source.Velocity );
|
||
}
|
||
|
||
void PerFinger_OnTap( TapGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerTap( finger.Index, source.Position );
|
||
}
|
||
|
||
void PerFinger_OnDoubleTap( MultiTapGestureRecognizer source )
|
||
{
|
||
Finger finger = GetFingerFromTouchFilter( source );
|
||
RaiseOnFingerDoubleTap( finger.Index, source.Position );
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region Finger List Data Structure
|
||
|
||
/// <summary>
|
||
/// Represent a read-only list of fingers, augmented with a bunch of utility methods
|
||
/// </summary>
|
||
public interface IFingerList : IEnumerable<Finger>
|
||
{
|
||
/// <summary>
|
||
/// Get finger in array by index
|
||
/// </summary>
|
||
/// <param name="index">The array index</param>
|
||
Finger this[int index] { get; }
|
||
|
||
/// <summary>
|
||
/// Number of fingers in the list
|
||
/// </summary>
|
||
int Count { get; }
|
||
|
||
/// <summary>
|
||
/// Get the average position of all the fingers in the list
|
||
/// </summary>
|
||
Vector2 GetAveragePosition();
|
||
|
||
/// <summary>
|
||
/// Get the average previous position of all the fingers in the list
|
||
/// </summary>
|
||
Vector2 GetAveragePreviousPosition();
|
||
|
||
/// <summary>
|
||
/// Get the average distance from each finger's starting position in the list
|
||
/// </summary>
|
||
float GetAverageDistanceFromStart();
|
||
|
||
/// <summary>
|
||
/// Find the finger with the oldest StartTime
|
||
/// </summary>
|
||
Finger GetOldest();
|
||
}
|
||
|
||
/// <summary>
|
||
/// A finger list implementation with support for write access
|
||
/// </summary>
|
||
public class FingerList : IFingerList
|
||
{
|
||
List<Finger> list;
|
||
|
||
public FingerList()
|
||
{
|
||
list = new List<Finger>();
|
||
}
|
||
|
||
public FingerList( List<Finger> list )
|
||
{
|
||
this.list = list;
|
||
}
|
||
|
||
public Finger this[int index]
|
||
{
|
||
get { return list[index]; }
|
||
}
|
||
|
||
public int Count
|
||
{
|
||
get { return list.Count; }
|
||
}
|
||
|
||
public IEnumerator<Finger> GetEnumerator()
|
||
{
|
||
return list.GetEnumerator();
|
||
}
|
||
|
||
IEnumerator IEnumerable.GetEnumerator()
|
||
{
|
||
return GetEnumerator();
|
||
}
|
||
|
||
public void Add( Finger touch )
|
||
{
|
||
list.Add( touch );
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
list.Clear();
|
||
}
|
||
|
||
public delegate T FingerPropertyGetterDelegate<T>( Finger finger );
|
||
|
||
public Vector2 AverageVector( FingerPropertyGetterDelegate<Vector2> getProperty )
|
||
{
|
||
Vector2 avg = Vector2.zero;
|
||
|
||
if( Count > 0 )
|
||
{
|
||
for (int i = 0; i < list.Count; i++)
|
||
{
|
||
avg += getProperty(list[i]);
|
||
}
|
||
avg /= Count;
|
||
}
|
||
|
||
return avg;
|
||
}
|
||
|
||
public float AverageFloat( FingerPropertyGetterDelegate<float> getProperty )
|
||
{
|
||
float avg = 0;
|
||
|
||
if( Count > 0 )
|
||
{
|
||
|
||
for (int i = 0; i < list.Count;i++ )
|
||
{
|
||
avg += getProperty(list[i]);
|
||
}
|
||
|
||
avg /= Count;
|
||
}
|
||
|
||
return avg;
|
||
}
|
||
|
||
static Vector2 GetFingerPosition( Finger finger ) { return finger.Position; }
|
||
static Vector2 GetFingerPreviousPosition( Finger finger ) { return finger.PreviousPosition; }
|
||
static float GetFingerDistanceFromStart( Finger finger ) { return finger.DistanceFromStart; }
|
||
|
||
public Vector2 GetAveragePosition()
|
||
{
|
||
return AverageVector( GetFingerPosition );
|
||
}
|
||
|
||
public Vector2 GetAveragePreviousPosition()
|
||
{
|
||
return AverageVector( GetFingerPreviousPosition );
|
||
}
|
||
|
||
public float GetAverageDistanceFromStart()
|
||
{
|
||
return AverageFloat( GetFingerDistanceFromStart );
|
||
}
|
||
|
||
public Finger GetOldest()
|
||
{
|
||
Finger oldest = null;
|
||
|
||
for (int i = 0; i < list.Count;i++ )
|
||
{
|
||
if (oldest == null || (list[i].StarTime < oldest.StarTime))
|
||
oldest = list[i];
|
||
}
|
||
|
||
return oldest;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Swipe Direction
|
||
|
||
/// <summary>
|
||
/// Supported swipe gesture directions
|
||
/// </summary>
|
||
[System.Flags]
|
||
public enum SwipeDirection
|
||
{
|
||
/// <summary>
|
||
/// Moved to the right
|
||
/// </summary>
|
||
Right = 1 << 0,
|
||
|
||
/// <summary>
|
||
/// Moved to the left
|
||
/// </summary>
|
||
Left = 1 << 1,
|
||
|
||
/// <summary>
|
||
/// Moved up
|
||
/// </summary>
|
||
Up = 1 << 2,
|
||
|
||
/// <summary>
|
||
/// Moved down
|
||
/// </summary>
|
||
Down = 1 << 3,
|
||
|
||
//--------------------
|
||
|
||
None = 0,
|
||
All = Right | Left | Up | Down,
|
||
Vertical = Up | Down,
|
||
Horizontal = Right | Left,
|
||
}
|
||
|
||
/// <summary>
|
||
/// Extract a swipe direction from a direction vector and a tolerance percent
|
||
/// </summary>
|
||
/// <param name="dir">The non-constrained direction vector. Must be normalized.</param>
|
||
/// <param name="tolerance">Percentage of tolerance</param>
|
||
/// <returns>The swipe direction</returns>
|
||
public static SwipeDirection GetSwipeDirection( Vector3 dir, float tolerance )
|
||
{
|
||
float minSwipeDot = Mathf.Clamp01( 1.0f - tolerance );
|
||
|
||
if( Vector2.Dot( dir, Vector2.right ) >= minSwipeDot )
|
||
return SwipeDirection.Right;
|
||
|
||
if( Vector2.Dot( dir, -Vector2.right ) >= minSwipeDot )
|
||
return SwipeDirection.Left;
|
||
|
||
if( Vector2.Dot( dir, Vector2.up ) >= minSwipeDot )
|
||
return SwipeDirection.Up;
|
||
|
||
if( Vector2.Dot( dir, -Vector2.up ) >= minSwipeDot )
|
||
return SwipeDirection.Down;
|
||
|
||
// not a valid direction
|
||
return SwipeDirection.None;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Single-Finger Touch Filter
|
||
|
||
/// <summary>
|
||
/// A touch filter can be used to alter the content of the input touches list initially given to each Gesture Recognizer
|
||
/// </summary>
|
||
public interface ITouchFilter
|
||
{
|
||
/// <summary>
|
||
/// Apply the filter to the input touches list, returning a (possibly) modified list which is then consumed by the GestureRecognizer
|
||
/// </summary>
|
||
/// <param name="touches">The unaltered list of touches</param>
|
||
/// <returns>The modified list of touches</returns>
|
||
FingerGestures.IFingerList Apply( FingerGestures.IFingerList touches );
|
||
}
|
||
|
||
/// <summary>
|
||
/// A single-finger touch filter that:
|
||
/// - returns an list composed of its unique finger if it is contained in the the input list
|
||
/// - returns an empty list otherwise
|
||
/// This has the benefit of requiring no run-time dynamic allocations (except once at creation)
|
||
/// </summary>
|
||
public class SingleFingerFilter : ITouchFilter
|
||
{
|
||
FingerList fingerList = new FingerList();
|
||
FingerList emptyList = new FingerList();
|
||
|
||
Finger finger;
|
||
public Finger Finger
|
||
{
|
||
get { return finger; }
|
||
}
|
||
|
||
public SingleFingerFilter( Finger finger )
|
||
{
|
||
this.finger = finger;
|
||
fingerList.Add( finger );
|
||
}
|
||
|
||
public IFingerList Apply( IFingerList touches )
|
||
{
|
||
for (int i = 0; i < touches.Count; i++)
|
||
{
|
||
if (touches[i] == Finger)
|
||
{
|
||
return fingerList;
|
||
}
|
||
}
|
||
return emptyList;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Utils
|
||
|
||
/// <summary>
|
||
/// Check if all the fingers in the list are moving
|
||
/// </summary>
|
||
public static bool AllFingersMoving( params Finger[] fingers )
|
||
{
|
||
int fingersLen = fingers.Length;
|
||
if(fingersLen == 0)
|
||
return false;
|
||
for(int i = 0, imax = fingersLen; i < fingersLen; i++)
|
||
{
|
||
Finger finger = fingers[i];
|
||
if(finger != null && finger.Phase != FingerPhase.Moved)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check if the input fingers are moving in opposite direction
|
||
/// </summary>
|
||
public static bool FingersMovedInOppositeDirections( Finger finger0, Finger finger1, float minDOT )
|
||
{
|
||
float dot = Vector2.Dot( finger0.DeltaPosition.normalized, finger1.DeltaPosition.normalized );
|
||
return dot < minDOT;
|
||
}
|
||
|
||
/// <summary>
|
||
/// returns signed angle in radians between "from" -> "to"
|
||
/// </summary>
|
||
public static float SignedAngle( Vector2 from, Vector2 to )
|
||
{
|
||
// perpendicular dot product
|
||
float perpDot = ( from.x * to.y ) - ( from.y * to.x );
|
||
return Mathf.Atan2( perpDot, Vector2.Dot( from, to ) );
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// <20><>װarray foreach<63><68><EFBFBD><EFBFBD> // help for foreacha
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="tagArray"></param>
|
||
/// <param name="foreachFunc"></param>
|
||
protected static void DoForeachIteratively<T>(T[] tagArray, Action<T, int> foreachFunc = null)
|
||
{
|
||
if(tagArray != null)
|
||
{
|
||
for(int i = 0, imax = tagArray.Length; i < imax; i++)
|
||
{
|
||
T curElement = tagArray[i];
|
||
if(foreachFunc != null && curElement != null)
|
||
{
|
||
foreachFunc( curElement, i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
protected static void DoForeach<T>(T[] tagArray, Action<T> foreachFunc = null)
|
||
{
|
||
if(tagArray != null)
|
||
{
|
||
for(int i = 0, imax = tagArray.Length; i < imax; i++)
|
||
{
|
||
T curElement = tagArray[i];
|
||
if(foreachFunc != null && curElement != null)
|
||
{
|
||
foreachFunc( curElement );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|