protected virtual void Update() { // Make sure the camera exists cachedCamera = LeanHelper.GetCamera(Camera, gameObject); if (cachedCamera != null) { // Get the fingers we want to use var fingers = Use.GetFingers(); if (fingers.Count > 0) { // If it's the first frame the fingers are down, grab the current screen point of this GameObject if (targetSet == false) { targetSet = true; targetScreenPoint = cachedCamera.WorldToScreenPoint(transform.position); } // Shift target point based on finger deltas // NOTE: targetScreenPoint.z already stores the depth targetScreenPoint += (Vector3)LeanGesture.GetScreenDelta(fingers); } // Unset if no fingers are down else { targetSet = false; } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
protected virtual void Translate(float twistDegrees, Vector2 twistScreenCenter) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { // Screen position of the transform var screenPoint = camera.WorldToScreenPoint(transform.position); // Twist screen point around the twistScreenCenter by twistDegrees var twistRotation = Quaternion.Euler(0.0f, 0.0f, twistDegrees); var screenDelta = twistRotation * ((Vector2)screenPoint - twistScreenCenter); screenPoint.x = twistScreenCenter.x + screenDelta.x; screenPoint.y = twistScreenCenter.y + screenDelta.y; // Convert back to world space transform.position = camera.ScreenToWorldPoint(screenPoint); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
protected virtual void Update() { // Is this selected and has a selecting finger? if (Selectable != null && Selectable.IsSelected == true) { var finger = Selectable.SelectingFinger; if (finger != null) { // Camera exists? var camera = LeanHelper.GetCamera(null); if (camera != null) { // Find the screen point of the finger using the depth of this block var screenPoint = new Vector3(finger.ScreenPosition.x, finger.ScreenPosition.y, camera.WorldToScreenPoint(transform.position).z); // Find the world space point under the finger var worldPoint = camera.ScreenToWorldPoint(screenPoint); // Find the block coordinate at this point var dragX = Mathf.RoundToInt(worldPoint.x / BlockSize); var dragY = Mathf.RoundToInt(worldPoint.y / BlockSize); // Is this block right next to this one? var distX = Mathf.Abs(X - dragX); var distY = Mathf.Abs(Y - dragY); if (distX + distY == 1) { // Swap blocks if one exists at this coordinate var block = FindBlock(dragX, dragY); if (block != null) { Swap(this, block); if (DeselectOnSwap == true) { Selectable.Deselect(); } } } } } } // Smoothly move to new position var targetPosition = Vector3.zero; var factor = LeanHelper.GetDampenFactor(Damping, Time.deltaTime); targetPosition.x = X * BlockSize; targetPosition.y = Y * BlockSize; transform.localPosition = Vector3.Lerp(transform.localPosition, targetPosition, factor); }
private void UpdateTranslation() { var finalTransform = Target != null ? Target : transform; // Get the fingers we want to use var fingers = Use.GetFingers(); // Calculate the screenDelta value based on these fingers var screenDelta = LeanGesture.GetScreenDelta(fingers); // Make sure the camera exists var camera = LeanHelper.GetCamera(ScreenDepth.Camera, gameObject); if (fingers.Count == 0) { deltaDifference = Vector2.zero; } if (camera != null) { var worldPosition = finalTransform.position; var oldScreenPoint = camera.WorldToScreenPoint(worldPosition); if (TrackScreenPosition == true) { if (ScreenDepth.TryConvert(ref worldPosition, oldScreenPoint + (Vector3)(screenDelta + deltaDifference), gameObject) == true) { finalTransform.position = worldPosition; } var newScreenPoint = camera.WorldToScreenPoint(worldPosition); var oldNewDelta = (Vector2)(newScreenPoint - oldScreenPoint); deltaDifference += screenDelta - oldNewDelta; } else { if (ScreenDepth.TryConvert(ref worldPosition, oldScreenPoint + (Vector3)screenDelta, gameObject) == true) { finalTransform.position = worldPosition; } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
protected virtual void Rotate(float twistDegrees) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var axis = transform.InverseTransformDirection(camera.transform.forward); transform.rotation *= Quaternion.AngleAxis(twistDegrees, axis); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
/// <summary>This will return the change in world position of this finger based on the last and current distance from the camera.</summary> public Vector3 GetWorldDelta(float lastDistance, float distance, Camera camera = null) { // Make sure the camera exists camera = LeanHelper.GetCamera(camera); if (camera != null) { return(GetWorldPosition(distance, camera) - GetLastWorldPosition(lastDistance, camera)); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component."); } return(default(Vector3)); }
/// <summary>This will return the ray of the finger's start position relative to the specified camera (none/null = Main Camera).</summary> public Ray GetStartRay(Camera camera = null) { // Make sure the camera exists camera = LeanHelper.GetCamera(camera); if (camera != null) { return(camera.ScreenPointToRay(StartScreenPosition)); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component."); } return(default(Ray)); }
/// <summary>This will return the world position of this finger based on the distance from the camera.</summary> public Vector3 GetWorldPosition(float distance, Camera camera = null) { // Make sure the camera exists camera = LeanHelper.GetCamera(camera); if (camera != null) { var point = new Vector3(ScreenPosition.x, ScreenPosition.y, distance); return(camera.ScreenToWorldPoint(point)); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component."); } return(default(Vector3)); }
protected void SetZoom(float current) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { if (camera.orthographic == true) { camera.orthographicSize = current; } else { camera.fieldOfView = current; } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
private void Translate(Vector2 screenDelta) { // Make sure the camera exists var camera = LeanHelper.GetCamera(this._camera, gameObject); if (camera != null) { // Screen position of the transform var screenPoint = camera.WorldToScreenPoint(transform.position); // Add the deltaPosition screenPoint += (Vector3)screenDelta * Sensitivity; // Convert back to world space transform.position = camera.ScreenToWorldPoint(screenPoint); } else { Debug.LogError("Failed to find camera. Either tag your camera as MainCamera, or set one in this component.", this); } }
protected virtual void Update() { // Is this GameObject selected? if (Selectable != null && Selectable.IsSelected == true) { // Does it have a selected finger? var finger = Selectable.SelectingFinger; if (finger != null) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var newScaledDelta = finger.ScaledDelta; if (oldScaledDelta != Vector2.zero && newScaledDelta != Vector2.zero) { var angleA = Mathf.Atan2(oldScaledDelta.y, oldScaledDelta.x) * Mathf.Rad2Deg; var angleB = Mathf.Atan2(newScaledDelta.y, newScaledDelta.x) * Mathf.Rad2Deg; var torque = Mathf.DeltaAngle(angleA, angleB) * (oldScaledDelta.magnitude + newScaledDelta.magnitude); if (cachedRigidbody == null) { cachedRigidbody = GetComponent <Rigidbody>(); } cachedRigidbody.AddTorque(camera.transform.forward * torque * Force, ForceMode.Acceleration); } oldScaledDelta = newScaledDelta; } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } } }
protected virtual void Translate(float pinchScale, Vector2 screenCenter) { // Make sure the camera exists var camera = LeanHelper.GetCamera(_camera, gameObject); if (camera != null) { // Screen position of the transform var screenPosition = camera.WorldToScreenPoint(transform.position); // Push the screen position away from the reference point based on the scale screenPosition.x = screenCenter.x + (screenPosition.x - screenCenter.x) * pinchScale; screenPosition.y = screenCenter.y + (screenPosition.y - screenCenter.y) * pinchScale; // Convert back to world space transform.position = camera.ScreenToWorldPoint(screenPosition); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
private Vector2 GetPoint(Vector2 screenPoint) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var rectTransform = transform as RectTransform; if (rectTransform != null) { var worldPoint = default(Vector3); if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, screenPoint, camera, out worldPoint) == true) { return(Quaternion.LookRotation(Axis) * transform.InverseTransformPoint(worldPoint)); } } else { var ray = camera.ScreenPointToRay(screenPoint); var plane = new Plane(transform.TransformDirection(Axis), transform.position); var distance = default(float); if (plane.Raycast(ray, out distance) == true) { return(Quaternion.Inverse(Quaternion.LookRotation(Axis)) * transform.InverseTransformPoint(ray.GetPoint(distance))); } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } return(oldPoint); }
// Transform rect based on finger data private void WriteTransform(RectTransform rect, LeanFinger finger) { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var min = camera.ScreenToViewportPoint(finger.StartScreenPosition); var max = camera.ScreenToViewportPoint(finger.ScreenPosition); // Fix any inverted values if (min.x > max.x) { var t = min.x; min.x = max.x; max.x = t; } if (min.y > max.y) { var t = min.y; min.y = max.y; max.y = t; } // Reset pivot in case you forgot rect.pivot = Vector2.zero; // Set anchors rect.anchorMin = min; rect.anchorMax = max; // Make rect we check against var viewportRect = new Rect(); viewportRect.min = min; viewportRect.max = max; // Rebuild list of all selectables within rect selectables.Clear(); foreach (var selectable in LeanSelectable.Instances) { var viewportPoint = camera.WorldToViewportPoint(selectable.transform.position); if (viewportRect.Contains(viewportPoint) == true) { selectables.Add(selectable); } } // Select them LeanSelectable.ReplaceSelection(finger, selectables); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }
protected void TryGetComponent(SelectType selectUsing, Vector2 screenPosition, ref Component component, ref Vector3 worldPosition) { switch (selectUsing) { case SelectType.Raycast3D: { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { if (camera.pixelRect.Contains(screenPosition) == true) { var ray = camera.ScreenPointToRay(screenPosition); var count = Physics.RaycastNonAlloc(ray, raycastHits, float.PositiveInfinity, LayerMask); if (count > 0) { var closestHit = raycastHits[GetClosestRaycastHitsIndex(count)]; component = closestHit.transform; worldPosition = closestHit.point; } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; case SelectType.Overlap2D: { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { if (camera.pixelRect.Contains(screenPosition) == true) { var ray = camera.ScreenPointToRay(screenPosition); var slope = -ray.direction.z; if (slope != 0.0f) { var point = ray.GetPoint(ray.origin.z / slope); component = Physics2D.OverlapPoint(point, LayerMask); if (component != null) { worldPosition = component.transform.position; } } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; case SelectType.CanvasUI: { var results = LeanTouch.RaycastGui(screenPosition, LayerMask); if (results != null && results.Count > 0) { var firstTransform = results[0].gameObject.transform; component = firstTransform; worldPosition = firstTransform.position; } } break; case SelectType.ScreenDistance: { var bestDistance = MaxScreenDistance * LeanTouch.ScalingFactor; bestDistance *= bestDistance; // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { if (camera.pixelRect.Contains(screenPosition) == true) { foreach (var selectable in LeanSelectable.Instances) { var distance = Vector2.SqrMagnitude(GetScreenPoint(camera, selectable.transform) - screenPosition); if (distance <= bestDistance) { bestDistance = distance; component = selectable; worldPosition = selectable.transform.position; } } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; case SelectType.Intersect2D: { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { if (camera.pixelRect.Contains(screenPosition) == true) { var ray = camera.ScreenPointToRay(screenPosition); var count = Physics2D.GetRayIntersectionNonAlloc(ray, raycastHit2Ds, float.PositiveInfinity, LayerMask); if (count > 0) { var firstHit = raycastHit2Ds[0]; component = firstHit.transform; worldPosition = firstHit.point; } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; } }
// This will do the actual conversion public bool TryConvert(ref Vector3 position, Vector2 screenPoint, GameObject gameObject = null, Transform ignore = null) { var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { switch (Conversion) { case ConversionType.FixedDistance: { var screenPoint3 = new Vector3(screenPoint.x, screenPoint.y, Distance); position = camera.ScreenToWorldPoint(screenPoint3); LastWorldNormal = -camera.transform.forward; return(true); } case ConversionType.DepthIntercept: { var ray = camera.ScreenPointToRay(screenPoint); var slope = -ray.direction.z; if (slope != 0.0f) { var scale = (ray.origin.z - Distance) / slope; position = ray.GetPoint(scale); LastWorldNormal = Vector3.back; return(true); } } break; case ConversionType.PhysicsRaycast: { var ray = camera.ScreenPointToRay(screenPoint); var hitCount = Physics.RaycastNonAlloc(ray, hits, float.PositiveInfinity, Layers); var bestPoint = default(Vector3); var bestDist = float.PositiveInfinity; for (var i = hitCount - 1; i >= 0; i--) { var hit = hits[i]; var hitDistance = hit.distance; if (hitDistance < bestDist && IsChildOf(hit.transform, ignore) == false) { bestPoint = hit.point + hit.normal * Distance; bestDist = hitDistance; LastWorldNormal = hit.normal; } } if (bestDist < float.PositiveInfinity) { position = bestPoint; return(true); } } break; case ConversionType.PlaneIntercept: { var plane = default(LeanPlane); if (Exists(gameObject, ref plane) == true) { var ray = camera.ScreenPointToRay(screenPoint); var hit = default(Vector3); if (plane.TryRaycast(ray, ref hit, Distance) == true) { position = hit; LastWorldNormal = plane.transform.forward; return(true); } } } break; case ConversionType.PathClosest: { var path = default(LeanPath); if (Exists(gameObject, ref path) == true) { var ray = camera.ScreenPointToRay(screenPoint); if (path.TryGetClosest(ray, ref position, -1, Distance * Time.deltaTime) == true) { LastWorldNormal = LeanPath.LastWorldNormal; return(true); } } } break; case ConversionType.AutoDistance: { if (gameObject != null) { var depth = camera.WorldToScreenPoint(gameObject.transform.position).z; var screenPoint3 = new Vector3(screenPoint.x, screenPoint.y, depth + Distance); position = camera.ScreenToWorldPoint(screenPoint3); LastWorldNormal = -camera.transform.forward; return(true); } } break; case ConversionType.HeightIntercept: { var ray = camera.ScreenPointToRay(screenPoint); var slope = -ray.direction.y; if (slope != 0.0f) { var scale = (ray.origin.y - Distance) / slope; position = ray.GetPoint(scale); LastWorldNormal = Vector3.down; return(true); } } break; } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", gameObject); } return(false); }
protected override void OnSelectUp(LeanFinger finger) { // Stores the component we hit (Collider or Collider2D) var component = default(Component); switch (SelectUsing) { case SelectType.Raycast3D: { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var ray = camera.ScreenPointToRay(finger.ScreenPosition); var hit = default(RaycastHit); if (Physics.Raycast(ray, out hit, float.PositiveInfinity, LayerMask) == true) { component = hit.collider; } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; case SelectType.Overlap2D: { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { var ray = camera.ScreenPointToRay(finger.ScreenPosition); var count = Physics2D.GetRayIntersectionNonAlloc(ray, raycastHit2Ds, float.PositiveInfinity, LayerMask); if (count > 0) { component = raycastHit2Ds[0].transform; } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } } break; case SelectType.CanvasUI: { var results = LeanTouch.RaycastGui(finger.ScreenPosition, LayerMask); if (results != null && results.Count > 0) { component = results[0].gameObject.transform; } } break; } // Select the component Drop(finger, component); }
protected virtual void Update() { // Make sure the camera exists var camera = LeanHelper.GetCamera(Camera, gameObject); if (camera != null) { // Get the fingers we want to use to translate var fingers = Use.GetFingers(); if (cachedMeshFilter == null) { cachedMeshFilter = GetComponent <MeshFilter>(); } if (cachedMeshFilter.sharedMesh != null) { // Duplicate mesh? if (deformedMesh == null) { deformedMesh = cachedMeshFilter.sharedMesh = Instantiate(cachedMeshFilter.sharedMesh); } // Duplicate vertices if (deformedVertices == null || deformedVertices.Length != cachedMeshFilter.sharedMesh.vertexCount) { deformedVertices = cachedMeshFilter.sharedMesh.vertices; } var scalingFactor = LeanTouch.ScalingFactor; var deformed = false; // Go through all vertices and find the screen point for (var i = deformedVertices.Length - 1; i >= 0; i--) { var worldPoint = transform.TransformPoint(deformedVertices[i]); var screenPoint = camera.WorldToScreenPoint(worldPoint); // Go through all fingers for this vertex for (var j = fingers.Count - 1; j >= 0; j--) { var finger = fingers[j]; var scaledDist = Vector2.Distance(screenPoint, finger.ScreenPosition) * scalingFactor; // Is this finger within the required scaled radius of the vertex? if (scaledDist <= ScaledRadius) { deformed = true; // Shift screen point screenPoint.x += finger.ScreenDelta.x; screenPoint.y += finger.ScreenDelta.y; // Untransform it back to local space and write worldPoint = camera.ScreenToWorldPoint(screenPoint); deformedVertices[i] = transform.InverseTransformPoint(worldPoint); } } } // If deformed, apply changes if (deformed == true) { deformedMesh.vertices = deformedVertices; deformedMesh.RecalculateBounds(); deformedMesh.RecalculateNormals(); if (ApplyToMeshCollider == true) { if (cachedMeshCollider == null) { cachedMeshCollider = GetComponent <MeshCollider>(); } if (cachedMeshCollider != null) { cachedMeshCollider.sharedMesh = null; // Set to null first to force it to update cachedMeshCollider.sharedMesh = deformedMesh; } } } } } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component.", this); } }