Skip to content
Permalink
Browse files

- Gesture.ScreenPosition now returns activePointers[0].Position.

- Transform gestures ScreenPosition now return activePointers[0].Position.
- Moved CombineTouches functionality from Gesture to TapGesture since it is the only place it is used.
  • Loading branch information...
valyard committed Jul 25, 2017
1 parent 3b612b8 commit 73a3799d9f842b228603e3f117fd09f29e6ab1ba
@@ -29,19 +29,16 @@ internal class GestureEditor : UnityEditor.Editor
public static readonly GUIContent TEXT_SEND_STATE_CHANGE_MESSAGES = new GUIContent("Send State Change Messages", "If checked, the gesture will send a message for every state change. Gestures usually have their own more specific messages, so you should keep this toggle unchecked unless you really want state change messages.");
public static readonly GUIContent TEXT_SEND_MESSAGE_TARGET = new GUIContent("Target", "The GameObject target of Unity Messages. If null, host GameObject is used.");
public static readonly GUIContent TEXT_SEND_STATE_CHANGE_EVENTS = new GUIContent("Send State Change Events", "If checked, the gesture will send a events for every state change. Gestures usually have their own more specific messages, so you should keep this toggle unchecked unless you really want state change events.");
public static readonly GUIContent TEXT_COMBINE_POINTERS = new GUIContent("Combine Pointers", "When several fingers are used to perform a tap, pointers released not earlier than <CombineInterval> seconds ago are used to calculate gesture's final screen position.");
public static readonly GUIContent TEXT_COMBINE_TOUCH_POINTERS = new GUIContent("Combine Interval (sec)", TEXT_COMBINE_POINTERS.tooltip);
public static readonly GUIContent TEXT_REQUIRE_GESTURE_TO_FAIL = new GUIContent("Require Other Gesture to Fail", "Another gesture must fail for this gesture to start.");
public static readonly GUIContent TEXT_LIMIT_POINTERS = new GUIContent(" Limit Pointers", "");

protected bool shouldDrawCombineTouches = false;
protected bool shouldDrawAdvanced = false;
protected bool shouldDrawGeneral = true;

private Gesture instance;

private SerializedProperty debugMode, friendlyGestures, requireGestureToFail,
minPointers, maxPointers, combinePointers, combinePointersInterval,
minPointers, maxPointers,
useSendMessage, sendMessageTarget, sendStateChangeMessages,
useUnityEvents, sendStateChangeEvents;
private SerializedProperty OnStateChange;
@@ -63,8 +60,6 @@ protected virtual void OnEnable()
debugMode = serializedObject.FindProperty("debugMode");
friendlyGestures = serializedObject.FindProperty("friendlyGestures");
requireGestureToFail = serializedObject.FindProperty("requireGestureToFail");
combinePointers = serializedObject.FindProperty("combinePointers");
combinePointersInterval = serializedObject.FindProperty("combinePointersInterval");
useSendMessage = serializedObject.FindProperty("useSendMessage");
sendMessageTarget = serializedObject.FindProperty("sendMessageTarget");
sendStateChangeMessages = serializedObject.FindProperty("sendStateChangeMessages");
@@ -246,28 +241,9 @@ protected virtual void drawSendMessage()

protected virtual void drawAdvanced()
{
drawCombineTouches();
drawDebug();
}

protected virtual void drawCombineTouches()
{
if (shouldDrawCombineTouches)
{
EditorGUILayout.PropertyField(combinePointers, TEXT_COMBINE_POINTERS);
if (combinePointers.boolValue)
{
EditorGUIUtility.labelWidth = 160;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(GUIContent.none, GUILayout.Width(10));
EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
EditorGUILayout.PropertyField(combinePointersInterval, TEXT_COMBINE_TOUCH_POINTERS);
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
}
}

protected virtual void drawDebug()
{
if (debugMode == null) return;
@@ -14,28 +14,40 @@ internal sealed class TapGestureEditor : GestureEditor
public static readonly GUIContent TEXT_TIME_LIMIT = new GUIContent("Limit Time (sec)", "Gesture fails if in <value> seconds user didn't do the required number of taps.");
public static readonly GUIContent TEXT_DISTANCE_LIMIT = new GUIContent("Limit Movement (cm)", "Gesture fails if taps are made more than <value> cm away from the first pointer position.");
public static readonly GUIContent TEXT_NUMBER_OF_TAPS_REQUIRED = new GUIContent("Number of Taps Required", "Number of taps required for this gesture to be recognized.");
public static readonly GUIContent TEXT_COMBINE_POINTERS = new GUIContent("Combine Pointers", "When several fingers are used to perform a tap, pointers released not earlier than <CombineInterval> seconds ago are used to calculate gesture's final screen position.");
public static readonly GUIContent TEXT_COMBINE_TOUCH_POINTERS = new GUIContent("Combine Interval (sec)", TEXT_COMBINE_POINTERS.tooltip);

private SerializedProperty numberOfTapsRequired, distanceLimit, timeLimit;
private SerializedProperty numberOfTapsRequired, distanceLimit, timeLimit, combinePointers, combinePointersInterval;
private SerializedProperty OnTap;

protected override void OnEnable()
{
numberOfTapsRequired = serializedObject.FindProperty("numberOfTapsRequired");
timeLimit = serializedObject.FindProperty("timeLimit");
distanceLimit = serializedObject.FindProperty("distanceLimit");
combinePointers = serializedObject.FindProperty("combinePointers");
combinePointersInterval = serializedObject.FindProperty("combinePointersInterval");

OnTap = serializedObject.FindProperty("OnTap");

shouldDrawCombineTouches = true;

base.OnEnable();
}

protected override void drawGeneral()
{
EditorGUIUtility.labelWidth = 180;
EditorGUILayout.IntPopup(numberOfTapsRequired, new[] {new GUIContent("One"), new GUIContent("Two"), new GUIContent("Three")}, new[] {1, 2, 3}, TEXT_NUMBER_OF_TAPS_REQUIRED, GUILayout.ExpandWidth(true));

EditorGUILayout.PropertyField(combinePointers, TEXT_COMBINE_POINTERS);
if (combinePointers.boolValue)
{
EditorGUIUtility.labelWidth = 160;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(GUIContent.none, GUILayout.Width(10));
EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true));
EditorGUILayout.PropertyField(combinePointersInterval, TEXT_COMBINE_TOUCH_POINTERS);
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
base.drawGeneral ();
}

@@ -47,11 +59,12 @@ protected override void drawLimits()
base.drawLimits();
}

protected override void drawUnityEvents ()
protected override void drawUnityEvents()
{
EditorGUILayout.PropertyField(OnTap);

base.drawUnityEvents();
}

}
}
@@ -200,29 +200,6 @@ public Gesture RequireGestureToFail
}
}

/// <summary>
/// Gets or sets the flag if pointers should be treated as a cluster.
/// </summary>
/// <value> <c>true</c> if pointers should be treated as a cluster; otherwise, <c>false</c>. </value>
/// <remarks>
/// At the end of a gesture when pointers are lifted off due to the fact that computers are faster than humans the very last pointer's position will be gesture's <see cref="ScreenPosition"/> after that. This flag is used to combine several pointers which from the point of a user were lifted off simultaneously and set their centroid as gesture's <see cref="ScreenPosition"/>.
/// </remarks>
public bool CombinePointers
{
get { return combinePointers; }
set { combinePointers = value; }
}

/// <summary>
/// Gets or sets time interval before gesture is recognized to combine all lifted pointers into a cluster to use its center as <see cref="ScreenPosition"/>.
/// </summary>
/// <value> Time in seconds to treat pointers lifted off during this interval as a single gesture. </value>
public float CombinePointersInterval
{
get { return combinePointersInterval; }
set { combinePointersInterval = value; }
}

/// <summary>
/// Gets or sets whether gesture should use Unity's SendMessage in addition to C# events.
/// </summary>
@@ -347,7 +324,7 @@ public virtual Vector2 ScreenPosition
if (!TouchManager.IsInvalidPosition(cachedScreenPosition)) return cachedScreenPosition;
return TouchManager.INVALID_POSITION;
}
return ClusterUtils.Get2DCenterPosition(activePointers);
return activePointers[0].Position;
}
}

@@ -365,7 +342,7 @@ public virtual Vector2 PreviousScreenPosition
return cachedPreviousScreenPosition;
return TouchManager.INVALID_POSITION;
}
return ClusterUtils.GetPrevious2DCenterPosition(activePointers);
return activePointers[0].PreviousPosition;
}
}

@@ -474,13 +451,6 @@ protected IGestureManager gestureManager
[SerializeField]
private int maxPointers = 0;

[SerializeField]
[ToggleLeft]
private bool combinePointers = false;

[SerializeField]
private float combinePointersInterval = .3f;

[SerializeField]
[ToggleLeft]
private bool useSendMessage = false;
@@ -509,7 +479,6 @@ protected IGestureManager gestureManager

private int numPointers;
private ReadOnlyCollection<Pointer> readonlyActivePointers;
private TimedSequence<Pointer> pointerSequence = new TimedSequence<Pointer>();
private GestureManagerInstance gestureManagerInstance;
private GestureState delayedStateChange = GestureState.Idle;
private bool requiredGestureFailed = false;
@@ -520,13 +489,13 @@ protected IGestureManager gestureManager
/// Cached screen position.
/// Used to keep tap's position which can't be calculated from pointers when the gesture is recognized since all pointers are gone.
/// </summary>
private Vector2 cachedScreenPosition;
protected Vector2 cachedScreenPosition;

/// <summary>
/// Cached previous screen position.
/// Used to keep tap's position which can't be calculated from pointers when the gesture is recognized since all pointers are gone.
/// </summary>
private Vector2 cachedPreviousScreenPosition;
protected Vector2 cachedPreviousScreenPosition;

#endregion

@@ -822,36 +791,20 @@ internal void INTERNAL_PointersReleased(IList<Pointer> pointers)
for (var i = 0; i < count; i++) activePointers.Remove(pointers[i]);
numPointers = total;

if (combinePointers)
{
for (var i = 0; i < count; i++) pointerSequence.Add(pointers[i]);

if (NumPointers == 0)
{
// Checking which points were removed in clusterExistenceTime seconds to set their centroid as cached screen position
var cluster = pointerSequence.FindElementsLaterThan(Time.time - combinePointersInterval,
shouldCachePointerPosition);
cachedScreenPosition = ClusterUtils.Get2DCenterPosition(cluster);
cachedPreviousScreenPosition = ClusterUtils.GetPrevious2DCenterPosition(cluster);
}
}
else
{
if (NumPointers == 0)
{
var lastPoint = pointers[count - 1];
if (shouldCachePointerPosition(lastPoint))
{
cachedScreenPosition = lastPoint.Position;
cachedPreviousScreenPosition = lastPoint.PreviousPosition;
}
else
{
cachedScreenPosition = TouchManager.INVALID_POSITION;
cachedPreviousScreenPosition = TouchManager.INVALID_POSITION;
}
}
}
if (NumPointers == 0)
{
var lastPoint = pointers[count - 1];
if (shouldCachePointerPosition(lastPoint))
{
cachedScreenPosition = lastPoint.Position;
cachedPreviousScreenPosition = lastPoint.PreviousPosition;
}
else
{
cachedScreenPosition = TouchManager.INVALID_POSITION;
cachedPreviousScreenPosition = TouchManager.INVALID_POSITION;
}
}

pointersReleased(pointers);
}
@@ -86,6 +86,29 @@ public float DistanceLimit
}
}

/// <summary>
/// Gets or sets the flag if pointers should be treated as a cluster.
/// </summary>
/// <value> <c>true</c> if pointers should be treated as a cluster; otherwise, <c>false</c>. </value>
/// <remarks>
/// At the end of a gesture when pointers are lifted off due to the fact that computers are faster than humans the very last pointer's position will be gesture's <see cref="ScreenPosition"/> after that. This flag is used to combine several pointers which from the point of a user were lifted off simultaneously and set their centroid as gesture's <see cref="ScreenPosition"/>.
/// </remarks>
public bool CombinePointers
{
get { return combinePointers; }
set { combinePointers = value; }
}

/// <summary>
/// Gets or sets time interval before gesture is recognized to combine all lifted pointers into a cluster to use its center as <see cref="ScreenPosition"/>.
/// </summary>
/// <value> Time in seconds to treat pointers lifted off during this interval as a single gesture. </value>
public float CombinePointersInterval
{
get { return combinePointersInterval; }
set { combinePointersInterval = value; }
}

#endregion

#region Private variables
@@ -95,13 +118,18 @@ public float DistanceLimit

[SerializeField]
[NullToggle(NullFloatValue = float.PositiveInfinity)]
private float timeLimit =
float.PositiveInfinity;
private float timeLimit = float.PositiveInfinity;

[SerializeField]
[NullToggle(NullFloatValue = float.PositiveInfinity)]
private float distanceLimit =
float.PositiveInfinity;
private float distanceLimit = float.PositiveInfinity;

[SerializeField]
[ToggleLeft]
private bool combinePointers = false;

[SerializeField]
private float combinePointersInterval = .3f;

private float distanceLimitInPixelsSquared;

@@ -111,6 +139,7 @@ public float DistanceLimit
private int tapsDone;
private Vector2 startPosition;
private Vector2 totalMovement;
private TimedSequence<Pointer> pointerSequence = new TimedSequence<Pointer>();

#endregion

@@ -208,27 +237,43 @@ protected override void pointersReleased(IList<Pointer> pointers)
{
base.pointersReleased(pointers);

if (NumPointers == 0)
{
if (!isActive)
{
setState(GestureState.Failed);
return;
}

// pointers outside of gesture target are ignored in shouldCachePointerPosition()
// if all pointers are outside ScreenPosition will be invalid
if (TouchManager.IsInvalidPosition(ScreenPosition))
{
setState(GestureState.Failed);
}
else
{
tapsDone++;
isActive = false;
if (tapsDone >= numberOfTapsRequired) setState(GestureState.Recognized);
}
}
if (combinePointers)
{
var count = pointers.Count;
for (var i = 0; i < count; i++) pointerSequence.Add(pointers[i]);

if (NumPointers == 0)
{
// Checking which points were removed in clusterExistenceTime seconds to set their centroid as cached screen position
var cluster = pointerSequence.FindElementsLaterThan(Time.time - combinePointersInterval, shouldCachePointerPosition);
cachedScreenPosition = ClusterUtils.Get2DCenterPosition(cluster);
cachedPreviousScreenPosition = ClusterUtils.GetPrevious2DCenterPosition(cluster);
}
}
else
{
if (NumPointers == 0)
{
if (!isActive)
{
setState(GestureState.Failed);
return;
}

// pointers outside of gesture target are ignored in shouldCachePointerPosition()
// if all pointers are outside ScreenPosition will be invalid
if (TouchManager.IsInvalidPosition(ScreenPosition))
{
setState(GestureState.Failed);
}
else
{
tapsDone++;
isActive = false;
if (tapsDone >= numberOfTapsRequired) setState(GestureState.Recognized);
}
}
}
}

/// <inheritdoc />
Oops, something went wrong.

0 comments on commit 73a3799

Please sign in to comment.
You can’t perform that action at this time.