private void Start() { panGesture = new PanGestureRecognizer { PlatformSpecificView = PanPlatformSpecificView, ThresholdUnits = PanGestureThresholdUnits }; panGesture.StateUpdated += Panned; tapGesture = new TapGestureRecognizer { ClearTrackedTouchesOnEndOrFail = true, MaximumNumberOfTouchesToTrack = 10, PlatformSpecificView = TapPlatformSpecificView, ThresholdUnits = TapGestureThresholdUnits }; tapGesture.StateUpdated += Tapped; tapGesture.AllowSimultaneousExecution(panGesture); if (!string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { crossPlatformInputHorizontalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputHorizontalAxisName, out crossPlatformInputAxisMoveNewlyRegistered); crossPlatformInputVerticalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputVerticalAxisName, out crossPlatformInputAxisMoveNewlyRegistered); } if (!string.IsNullOrEmpty(CrossPlatformInputJumpAxisName)) { crossPlatformInputJumpAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputJumpAxisName, out crossPlatformInputAxisJumpNewlyRegistered); } clearJumpAction = ClearJump; FingersScript.Instance.AddGesture(panGesture); FingersScript.Instance.AddGesture(tapGesture); }
private void OnEnable() { #if UNITY_EDITOR ValidateImages(DPadBackgroundImage, DPadUpImageSelected, DPadRightImageSelected, DPadDownImageSelected, DPadLeftImageSelected, DPadCenterImageSelected); #endif PanGesture = new PanGestureRecognizer { PlatformSpecificView = DPadBackgroundImage.gameObject, ThresholdUnits = 0.0f }; PanGesture.StateUpdated += PanGestureUpdated; FingersScript.Instance.AddGesture(PanGesture); TapGesture = new TapGestureRecognizer { PlatformSpecificView = DPadBackgroundImage.gameObject }; TapGesture.StateUpdated += TapGestureUpdated; TapGesture.AllowSimultaneousExecution(PanGesture); if (!string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { crossPlatformInputHorizontalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputHorizontalAxisName, out crossPlatformInputNewlyRegistered); crossPlatformInputVerticalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputVerticalAxisName, out crossPlatformInputNewlyRegistered); } FingersScript.Instance.AddGesture(TapGesture); }
private void ClearJump() { if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(CrossPlatformInputJumpAxisName, 0.0f); } }
private void OnEnable() { rectTransform = GetComponent <RectTransform>(); PanGesture = new PanGestureRecognizer { PlatformSpecificView = JoystickBackground.gameObject, ThresholdUnits = 0.0f }; PanGesture.AllowSimultaneousExecutionWithAllGestures(); PanGesture.StateUpdated += PanGestureUpdated; #if UNITY_EDITOR if (JoystickImage == null || JoystickImage.canvas.renderMode != RenderMode.ScreenSpaceOverlay) { Debug.LogError("Fingers joystick script requires that JoystickImage be set and that the Canvas be in ScreenSpaceOverlay mode."); } #endif if (!string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { crossPlatformInputHorizontalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputHorizontalAxisName, out crossPlatformInputNewlyRegistered); crossPlatformInputVerticalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputVerticalAxisName, out crossPlatformInputNewlyRegistered); } FingersScript.Instance.AddGesture(PanGesture); }
private void OnEnable() { rectTransform = GetComponent <RectTransform>(); rectTransform.pivot = new Vector2(0.5f, 0.5f); PanGesture.ThresholdUnits = 0.0f; PanGesture.AllowSimultaneousExecutionWithAllGestures(); PanGesture.StateUpdated += PanGestureUpdated; #if UNITY_EDITOR if (JoystickImage != null && JoystickImage.canvas.renderMode != RenderMode.ScreenSpaceOverlay) { Debug.LogError("Fingers joystick script requires that if JoystickImage is set, the Canvas is in ScreenSpaceOverlay mode."); } #endif if (!string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { crossPlatformInputHorizontalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputHorizontalAxisName, out crossPlatformInputNewlyRegistered); crossPlatformInputVerticalAxisObject = FingersCrossPlatformInputReflectionScript.RegisterVirtualAxis(CrossPlatformInputVerticalAxisName, out crossPlatformInputNewlyRegistered); } FingersScript.Instance.AddGesture(PanGesture); SetIdleState(); homePosition = rectTransform.position; }
private void OnDestroy() { if (crossPlatformInputNewlyRegistered && !string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { FingersCrossPlatformInputReflectionScript.UnRegisterVirtualAxis(CrossPlatformInputHorizontalAxisName); FingersCrossPlatformInputReflectionScript.UnRegisterVirtualAxis(CrossPlatformInputVerticalAxisName); } }
private void CheckForOverlap <T>(Vector2 point, T gesture, System.Action <FingersDPadScript, FingersDPadItem, T> action) where T : DigitalRubyShared.GestureRecognizer { if (action == null) { return; } FingersDPadItem item = FingersDPadItem.None; int count = Physics2D.OverlapCircleNonAlloc(point, DeviceInfo.UnitsToPixels(TouchRadiusInUnits), overlap); float horizontal = 0.0f; float vertical = 0.0f; for (int i = 0; i < count; i++) { if (overlap[i].gameObject == DPadCenterImageSelected.gameObject) { DPadCenterImageSelected.enabled = true; item |= FingersDPadItem.Center; } if (overlap[i].gameObject == DPadRightImageSelected.gameObject) { DPadRightImageSelected.enabled = true; item |= FingersDPadItem.Right; horizontal = 1.0f; } if (overlap[i].gameObject == DPadDownImageSelected.gameObject) { DPadDownImageSelected.enabled = true; item |= FingersDPadItem.Down; vertical = -1.0f; } if (overlap[i].gameObject == DPadLeftImageSelected.gameObject) { DPadLeftImageSelected.enabled = true; item |= FingersDPadItem.Left; horizontal = -1.0f; } if (overlap[i].gameObject == DPadUpImageSelected.gameObject) { DPadUpImageSelected.enabled = true; item |= FingersDPadItem.Up; vertical = 1.0f; } } if (item != FingersDPadItem.None) { action(this, item, gesture); if (horizontal != 0.0f && crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, horizontal); } if (vertical != 0.0f && crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, vertical); } } }
private void OnDisable() { if (FingersScript.HasInstance) { FingersScript.Instance.RemoveGesture(TapGesture); } if (crossPlatformInputNewlyRegistered && !string.IsNullOrEmpty(CrossPlatformInputHorizontalAxisName) && !string.IsNullOrEmpty(CrossPlatformInputVerticalAxisName)) { FingersCrossPlatformInputReflectionScript.UnRegisterVirtualAxis(CrossPlatformInputHorizontalAxisName); FingersCrossPlatformInputReflectionScript.UnRegisterVirtualAxis(CrossPlatformInputVerticalAxisName); } }
private void Tapped(GestureRecognizer tapGesture) { if (tapGesture.State == GestureRecognizerState.Ended && TapCallback != null) { TapCallback.Invoke(); if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputJumpAxisObject, 1.0f); // clear jump axis next frame so the player doesn't keep jumping GestureRecognizer.RunActionAfterDelay(0.001f, clearJumpAction); } } }
private void Update() { if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputJumpAxisObject, 0.0f); } if (PanAnchor != null && PanAnchor.enabled && PanAnchorLine != null && PanAnchorLine.enabled && panLocation != Vector2.zero) { Vector2 start = PanAnchor.transform.position; Vector2 end = panLocation; PanAnchorLine.DrawLine(start, end, 1.0f); } }
private void PanGestureUpdated(DigitalRubyShared.GestureRecognizer gesture) { if (gesture.State == GestureRecognizerState.Executing) { // clamp joystick movement to max values float maxOffset = (Screen.width + Screen.height) * MaxExtentPercent; Vector2 offset = new Vector2(gesture.FocusX - gesture.StartFocusX, gesture.FocusY - gesture.StartFocusY); // check distance from center, clamp to distance offset = Vector2.ClampMagnitude(offset, maxOffset); // don't bother if no motion if (offset == Vector2.zero) { return; } // handle eight axis offset param offset = UpdateForEightAxisMode(offset, maxOffset); // move image SetImagePosition(startCenter + offset); if (!AddUpToOne) { float maxOffsetLerp = maxOffset * 0.7f; offset.x = Mathf.Sign(offset.x) * Mathf.Lerp(0.0f, maxOffset, Mathf.Abs(offset.x / maxOffsetLerp)); offset.y = Mathf.Sign(offset.y) * Mathf.Lerp(0.0f, maxOffset, Mathf.Abs(offset.y / maxOffsetLerp)); } // callback with movement weight if (JoystickPower >= 1.0f) { // power is reducing offset, apply as is offset.x = Mathf.Sign(offset.x) * Mathf.Pow(Mathf.Abs(offset.x) / maxOffset, JoystickPower); offset.y = Mathf.Sign(offset.y) * Mathf.Pow(Mathf.Abs(offset.y) / maxOffset, JoystickPower); } else { // power is increasing offset, we need to make sure we maintain the aspect ratio of offset Vector2 absOffset = new Vector2(Mathf.Abs(offset.x), Mathf.Abs(offset.y)); float offsetTotal = absOffset.x + absOffset.y; float xWeight = absOffset.x / offsetTotal; float yWeight = absOffset.y / offsetTotal; offset.x = xWeight * Mathf.Sign(offset.x) * Mathf.Pow(absOffset.x / maxOffset, JoystickPower); offset.y = yWeight * Mathf.Sign(offset.y) * Mathf.Pow(absOffset.y / maxOffset, JoystickPower); offset = Vector2.ClampMagnitude(offset, maxOffset); } ExecuteCallback(offset); if (crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, offset.x); } if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, offset.y); } } else if (gesture.State == GestureRecognizerState.Began) { if (MoveJoystickToGestureStartLocation) { JoystickImage.transform.parent.position = new Vector3(gesture.FocusX, gesture.FocusY, JoystickImage.transform.parent.position.z); } startCenter = JoystickImage.rectTransform.anchoredPosition; } else if (gesture.State == GestureRecognizerState.Ended) { // return to center SetImagePosition(startCenter); // final callback ExecuteCallback(Vector2.zero); } }
private void Panned(GestureRecognizer panGesture) { if (panGesture.State == GestureRecognizerState.Began) { if (PanAnchor != null) { PanAnchor.enabled = true; PanAnchor.transform.position = new Vector3(panGesture.StartFocusX, panGesture.StartFocusY, PanAnchor.transform.position.z); } if (PanAnchorLine != null) { PanAnchorLine.enabled = true; PanAnchorLine.DrawLine(Vector2.zero, Vector2.zero, 0.0f); } } else if (panGesture.State == GestureRecognizerState.Executing) { float unitsX = DeviceInfo.PixelsToUnits(panGesture.DistanceX); float unitsY = DeviceInfo.PixelsToUnits(panGesture.DistanceY); float panX = Mathf.Sign(unitsX) * Mathf.Lerp(0.0f, 1.0f, Mathf.Abs(unitsX) / PanUnitsForMaxMove); float panY = Mathf.Sign(unitsY) * Mathf.Lerp(0.0f, 1.0f, Mathf.Abs(unitsY) / PanUnitsForMaxMove); if (PanCallback != null) { PanCallback.Invoke(new Vector2(panX, panY)); } if (crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, panX); } if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, panY); } if (PanAnchor != null) { panLocation = new Vector2(panGesture.FocusX, panGesture.FocusY); } } else if (panGesture.State == GestureRecognizerState.Ended || panGesture.State == GestureRecognizerState.Failed) { if (PanCallback != null) { PanCallback.Invoke(new Vector2(0.0f, 0.0f)); } if (crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, 0.0f); } if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, 0.0f); } if (PanAnchor != null) { PanAnchor.enabled = false; panLocation = Vector2.zero; } if (PanAnchorLine != null) { PanAnchorLine.enabled = false; } } }
private void PanGestureUpdated(DigitalRubyShared.GestureRecognizer gesture) { if (gesture.State == GestureRecognizerState.Executing) { // clamp joystick movement to max values float diameter = (rectTransform.rect.width + rectTransform.rect.height) * 0.5f; float radius = diameter * 0.5f; float maxOffset = radius * MaxRangeRadiusMultiplier; Vector2 gestureOffset = new Vector2(gesture.FocusX, gesture.FocusY); Vector2 offset; RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, gestureOffset, null, out offset); offset.x -= radius; offset.y -= radius; float distanceFromCenter = offset.magnitude; float overshoot = Mathf.Max(0.0f, distanceFromCenter - radius); Vector2 followVelocity = (offset.normalized * overshoot * FollowSpeed * Time.deltaTime); // check distance from center, clamp to distance offset = Vector2.ClampMagnitude(offset, maxOffset); // don't bother if no motion if (offset == Vector2.zero) { return; } // handle eight axis offset param offset = UpdateForEightAxisMode(offset, maxOffset); // move image SetImagePosition(startCenter + offset); if (!AddUpToOne) { float maxOffsetLerp = maxOffset * 0.7f; offset.x = Mathf.Sign(offset.x) * Mathf.Lerp(0.0f, maxOffset, Mathf.Abs(offset.x / maxOffsetLerp)); offset.y = Mathf.Sign(offset.y) * Mathf.Lerp(0.0f, maxOffset, Mathf.Abs(offset.y / maxOffsetLerp)); } // callback with movement weight if (JoystickPower >= 1.0f) { // power is reducing offset, apply as is offset.x = Mathf.Sign(offset.x) * Mathf.Pow(Mathf.Abs(offset.x) / maxOffset, JoystickPower); offset.y = Mathf.Sign(offset.y) * Mathf.Pow(Mathf.Abs(offset.y) / maxOffset, JoystickPower); } else { // power is increasing offset, we need to make sure we maintain the aspect ratio of offset Vector2 absOffset = new Vector2(Mathf.Abs(offset.x), Mathf.Abs(offset.y)); float offsetTotal = absOffset.x + absOffset.y; float xWeight = absOffset.x / offsetTotal; float yWeight = absOffset.y / offsetTotal; offset.x = xWeight * Mathf.Sign(offset.x) * Mathf.Pow(absOffset.x / maxOffset, JoystickPower); offset.y = yWeight * Mathf.Sign(offset.y) * Mathf.Pow(absOffset.y / maxOffset, JoystickPower); offset = Vector2.ClampMagnitude(offset, maxOffset); } ExecuteCallback(offset); if (crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, offset.x); } if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, offset.y); } transform.Translate(followVelocity); } else if (gesture.State == GestureRecognizerState.Began) { if (MoveJoystickToGestureStartLocation) { Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, new Vector2(gesture.FocusX, gesture.FocusY), null, out localPoint); float diameter = (rectTransform.rect.width + rectTransform.rect.height) * 0.5f; float radius = diameter * 0.5f; localPoint.x -= radius; localPoint.y -= radius; localPoint.x *= rectTransform.lossyScale.x; localPoint.y *= rectTransform.lossyScale.y; rectTransform.Translate(localPoint, Space.Self); } startCenter = JoystickImage.rectTransform.anchoredPosition; } else if (gesture.State == GestureRecognizerState.Ended) { // return to center SetImagePosition(startCenter); // final callback ExecuteCallback(Vector2.zero); } }
private void PanGestureUpdated(DigitalRubyShared.GestureRecognizer gesture) { if (gesture.State == GestureRecognizerState.Executing) { if (StartJoystick(gesture)) { // clamp joystick movement to max values float diameter = (rectTransform.rect.width + rectTransform.rect.height) * 0.5f; float radius = diameter * 0.5f; float maxOffset = radius * MaxRangeRadiusMultiplier; Vector2 gestureOffset = new Vector2(gesture.FocusX, gesture.FocusY); Vector2 offset; RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, gestureOffset, null, out offset); float distanceFromCenter = offset.magnitude; float overshoot = Mathf.Max(0.0f, distanceFromCenter - radius); Vector2 offsetNormalized = offset.normalized; Vector2 followVelocity = (offsetNormalized * overshoot * FollowSpeed); // check distance from center, clamp to distance offset = Vector2.ClampMagnitude(offset, maxOffset); // don't bother if no motion if (offset == Vector2.zero) { return; } // handle eight axis offset param offset = UpdateForEightAxisMode(offset, maxOffset); // move image SetImagePosition(startCenter + offset); // compute power in circle or square offsetNormalized = ComputeJoystickPowerCircle(offset, offsetNormalized, radius); ExecuteCallback(offsetNormalized); if (crossPlatformInputHorizontalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputHorizontalAxisObject, offset.x); } if (crossPlatformInputVerticalAxisObject != null) { FingersCrossPlatformInputReflectionScript.UpdateVirtualAxis(crossPlatformInputVerticalAxisObject, offset.y); } rectTransform.Translate(followVelocity); } } else if (gesture.State == GestureRecognizerState.Began) { StartJoystick(gesture); } else if (gesture.State == GestureRecognizerState.Ended) { // return to center SetImagePosition(startCenter); // reset state SetIdleState(); // final callback ExecuteCallback(Vector2.zero); if (ReturnToHomePosition) { // move to home rectTransform.position = homePosition; } } #if UNITY_2019_1_OR_NEWER if (RestrictJoystickPositionTo != null) { Vector2 closestPoint = RestrictJoystickPositionTo.ClosestPoint(rectTransform.position); rectTransform.position = closestPoint; } #endif }