// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved. using UnityEngine; namespace HutongGames.PlayMaker.Actions { // TODO: fairly basic right now // should have more options and be more robust, e.g., other fingers. [ActionCategory(ActionCategory.Device)] [Tooltip("Sends an event when a swipe is detected.")] public class SwipeGestureEvent : FsmStateAction { [Tooltip("How far a touch has to travel to be considered a swipe. Uses normalized distance (e.g. 1 = 1 screen diagonal distance). Should generally be a very small number.")] public FsmFloat minSwipeDistance; [Tooltip("Event to send when swipe left detected.")] public FsmEvent swipeLeftEvent; [Tooltip("Event to send when swipe right detected.")] public FsmEvent swipeRightEvent; [Tooltip("Event to send when swipe up detected.")] public FsmEvent swipeUpEvent; [Tooltip("Event to send when swipe down detected.")] public FsmEvent swipeDownEvent; // TODO /* [UIHint(UIHint.Variable)] [Tooltip("Store the speed of the swipe.")] public FsmFloat getSpeed; [UIHint(UIHint.Variable)] [Tooltip("Store the distance the swipe traveled.")] public FsmFloat getDistance;*/ float screenDiagonalSize; float minSwipeDistancePixels; bool touchStarted; Vector2 touchStartPos; //float touchStartTime; public override void Reset() { minSwipeDistance = 0.1f; swipeLeftEvent = null; swipeRightEvent = null; swipeUpEvent = null; swipeDownEvent = null; } public override void OnEnter() { screenDiagonalSize = Mathf.Sqrt(Screen.width * Screen.width + Screen.height * Screen.height); minSwipeDistancePixels = minSwipeDistance.Value * screenDiagonalSize; } public override void OnUpdate() { if (Input.touchCount > 0) { var touch = Input.touches[0]; switch (touch.phase) { case TouchPhase.Began: touchStarted = true; touchStartPos = touch.position; //touchStartTime = FsmTime.RealtimeSinceStartup; break; case TouchPhase.Ended: if (touchStarted) { TestForSwipeGesture(touch); touchStarted = false; } break; case TouchPhase.Canceled: touchStarted = false; break; case TouchPhase.Stationary: /* if (touchStarted) { // don't want idle time to count towards swipe touchStartPos = touch.position; touchStartTime = FsmTime.RealtimeSinceStartup; }*/ break; case TouchPhase.Moved: break; } } } void TestForSwipeGesture(Touch touch) { // test min distance var lastPos = touch.position; var distance = Vector2.Distance(lastPos, touchStartPos); if (distance > minSwipeDistancePixels) { float dy = lastPos.y - touchStartPos.y; float dx = lastPos.x - touchStartPos.x; float angle = Mathf.Rad2Deg * Mathf.Atan2(dx, dy); angle = (360 + angle - 45) % 360; Debug.Log (angle); if (angle < 90) { Fsm.Event(swipeRightEvent); } else if (angle < 180) { Fsm.Event(swipeDownEvent); } else if (angle < 270) { Fsm.Event(swipeLeftEvent); } else { Fsm.Event(swipeUpEvent); } } } } }