499 lines
16 KiB
C#
499 lines
16 KiB
C#
|
using UnityEngine;
|
|||
|
using System.Collections.Generic;
|
|||
|
using Lean.Common;
|
|||
|
|
|||
|
namespace Lean.Touch
|
|||
|
{
|
|||
|
/// <summary>This class stores information about a single touch (or simulated touch).</summary>
|
|||
|
public class LeanFinger
|
|||
|
{
|
|||
|
/// <summary>This is the hardware ID of the finger.
|
|||
|
/// NOTE: Simulated fingers will use hardware ID -1 and -2.</summary>
|
|||
|
public int Index;
|
|||
|
|
|||
|
/// <summary>This tells you how long this finger has been active (or inactive) in seconds.</summary>
|
|||
|
public float Age;
|
|||
|
|
|||
|
/// <summary>Is this finger currently touching the screen?</summary>
|
|||
|
public bool Set;
|
|||
|
|
|||
|
/// <summary>This tells you the 'Set' value of the last frame.</summary>
|
|||
|
public bool LastSet;
|
|||
|
|
|||
|
/// <summary>Did this finger just tap the screen?</summary>
|
|||
|
public bool Tap;
|
|||
|
|
|||
|
/// <summary>This tells you how many times this finger has been tapped.</summary>
|
|||
|
public int TapCount;
|
|||
|
|
|||
|
/// <summary>Did this finger just swipe the screen?</summary>
|
|||
|
public bool Swipe;
|
|||
|
|
|||
|
/// <summary>If this finger has been touching the screen for more than TapThreshold, this will be true.</summary>
|
|||
|
public bool Old;
|
|||
|
|
|||
|
/// <summary>If this finger has been inactive for more than TapThreshold, this will be true.</summary>
|
|||
|
public bool Expired;
|
|||
|
|
|||
|
/// <summary>This tells you the Pressure value last frame.</summary>
|
|||
|
public float LastPressure;
|
|||
|
|
|||
|
/// <summary>This tells you the current pressure of this finger (NOTE: only some devices support this).</summary>
|
|||
|
public float Pressure;
|
|||
|
|
|||
|
/// <summary>This tells you the 'ScreenPosition' value of this finger when it began touching the screen.</summary>
|
|||
|
public Vector2 StartScreenPosition;
|
|||
|
|
|||
|
/// <summary>This tells you the last screen position of the finger.</summary>
|
|||
|
public Vector2 LastScreenPosition;
|
|||
|
|
|||
|
/// <summary>This tells you the current screen position of the finger in pixels, where 0,0 = bottom left.</summary>
|
|||
|
public Vector2 ScreenPosition;
|
|||
|
|
|||
|
/// <summary>This tells you if the current finger had 'IsOverGui' set to true when it began touching the screen.</summary>
|
|||
|
public bool StartedOverGui;
|
|||
|
|
|||
|
/// <summary>Used to store position snapshots, enable RecordFingers in LeanTouch to use this.</summary>
|
|||
|
public List<LeanSnapshot> Snapshots = new List<LeanSnapshot>(1000);
|
|||
|
|
|||
|
/// <summary>This will return true if this finger is currently touching the screen.</summary>
|
|||
|
public bool IsActive
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return LeanTouch.Fingers.Contains(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will tell you how many seconds of snapshot footage is stored for this finger.</summary>
|
|||
|
public float SnapshotDuration
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (Snapshots.Count > 0)
|
|||
|
{
|
|||
|
return Age - Snapshots[0].Age;
|
|||
|
}
|
|||
|
|
|||
|
return 0.0f;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return true if the current finger is over any Unity GUI elements.</summary>
|
|||
|
public bool IsOverGui
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return LeanTouch.PointOverGui(ScreenPosition);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>Did this finger begin touching the screen this frame?</summary>
|
|||
|
public bool Down
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return Set == true && LastSet == false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>Did the finger stop touching the screen this frame?</summary>
|
|||
|
public bool Up
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return Set == false && LastSet == true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return how far in pixels the finger has moved since the last recorded snapshot.</summary>
|
|||
|
public Vector2 LastSnapshotScreenDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
var snapshotCount = Snapshots.Count;
|
|||
|
|
|||
|
if (snapshotCount > 0)
|
|||
|
{
|
|||
|
var snapshot = Snapshots[snapshotCount - 1];
|
|||
|
|
|||
|
if (snapshot != null)
|
|||
|
{
|
|||
|
return ScreenPosition - snapshot.ScreenPosition;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Vector2.zero;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'LastSnapshotScreenDelta' value.</summary>
|
|||
|
public Vector2 LastSnapshotScaledDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return LastSnapshotScreenDelta * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return how far in pixels the finger has moved since the last frame.</summary>
|
|||
|
public Vector2 ScreenDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return ScreenPosition - LastScreenPosition;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'ScreenDelta' value.</summary>
|
|||
|
public Vector2 ScaledDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return ScreenDelta * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This tells you how far this finger has moved since it began touching the screen.</summary>
|
|||
|
public Vector2 SwipeScreenDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return ScreenPosition - StartScreenPosition;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'SwipeScreenDelta' value.</summary>
|
|||
|
public Vector2 SwipeScaledDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return SwipeScreenDelta * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a smooth point between the previous and current screen position based on a 0..1 progress value.</summary>
|
|||
|
public Vector2 GetSmoothScreenPosition(float t)
|
|||
|
{
|
|||
|
if (Snapshots.Count > 0 && Set == true)
|
|||
|
{
|
|||
|
var d = Snapshots[Mathf.Max(0, Snapshots.Count - 4)].ScreenPosition;
|
|||
|
var c = Snapshots[Mathf.Max(0, Snapshots.Count - 3)].ScreenPosition;
|
|||
|
var b = Snapshots[Mathf.Max(0, Snapshots.Count - 2)].ScreenPosition;
|
|||
|
var a = Snapshots[Mathf.Max(0, Snapshots.Count - 1)].ScreenPosition;
|
|||
|
|
|||
|
return LeanHelper.Hermite(d, c, b, a, t);
|
|||
|
}
|
|||
|
|
|||
|
return Vector2.LerpUnclamped(LastScreenPosition, ScreenPosition, t);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns the screen space distance between the 0 and 1 smooth screen positions.</summary>
|
|||
|
public float SmoothScreenPositionDelta
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (Snapshots.Count > 0 && Set == true)
|
|||
|
{
|
|||
|
var c = Snapshots[Mathf.Max(0, Snapshots.Count - 3)].ScreenPosition;
|
|||
|
var b = Snapshots[Mathf.Max(0, Snapshots.Count - 2)].ScreenPosition;
|
|||
|
|
|||
|
return Vector2.Distance(c, b);
|
|||
|
}
|
|||
|
|
|||
|
return Vector2.Distance(LastScreenPosition, ScreenPosition);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the ray of the finger's current position relative to the specified camera (none/null = Main Camera).</summary>
|
|||
|
public Ray GetRay(Camera camera = null)
|
|||
|
{
|
|||
|
// Make sure the camera exists
|
|||
|
camera = LeanHelper.GetCamera(camera);
|
|||
|
|
|||
|
if (camera != null)
|
|||
|
{
|
|||
|
return camera.ScreenPointToRay(ScreenPosition);
|
|||
|
}
|
|||
|
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 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 tell you how far the finger has moved in the past 'deltaTime' seconds.</summary>
|
|||
|
public Vector2 GetSnapshotScreenDelta(float deltaTime)
|
|||
|
{
|
|||
|
return ScreenPosition - GetSnapshotScreenPosition(Age - deltaTime);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'GetSnapshotScreenDelta' value.</summary>
|
|||
|
public Vector2 GetSnapshotScaledDelta(float deltaTime)
|
|||
|
{
|
|||
|
return GetSnapshotScreenDelta(deltaTime) * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the recorded position of the current finger when it was at 'targetAge'.</summary>
|
|||
|
public Vector2 GetSnapshotScreenPosition(float targetAge)
|
|||
|
{
|
|||
|
var screenPosition = ScreenPosition;
|
|||
|
|
|||
|
LeanSnapshot.TryGetScreenPosition(Snapshots, targetAge, ref screenPosition);
|
|||
|
|
|||
|
return screenPosition;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the recorded world of the current finger when it was at 'targetAge'.</summary>
|
|||
|
public Vector3 GetSnapshotWorldPosition(float targetAge, float distance, Camera camera = null)
|
|||
|
{
|
|||
|
// Make sure the camera exists
|
|||
|
camera = LeanHelper.GetCamera(camera);
|
|||
|
|
|||
|
if (camera != null)
|
|||
|
{
|
|||
|
var screenPosition = GetSnapshotScreenPosition(targetAge);
|
|||
|
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);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the angle between the finger and the reference point, relative to the screen.</summary>
|
|||
|
public float GetRadians(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return Mathf.Atan2(ScreenPosition.x - referencePoint.x, ScreenPosition.y - referencePoint.y);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the angle between the finger and the reference point, relative to the screen.</summary>
|
|||
|
public float GetDegrees(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return GetRadians(referencePoint) * Mathf.Rad2Deg;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the angle between the last finger position and the reference point, relative to the screen.</summary>
|
|||
|
public float GetLastRadians(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return Mathf.Atan2(LastScreenPosition.x - referencePoint.x, LastScreenPosition.y - referencePoint.y);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the angle between the last finger position and the reference point, relative to the screen.</summary>
|
|||
|
public float GetLastDegrees(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return GetLastRadians(referencePoint) * Mathf.Rad2Deg;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the delta angle between the last and current finger position relative to the reference point.</summary>
|
|||
|
public float GetDeltaRadians(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return GetDeltaRadians(referencePoint, referencePoint);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the delta angle between the last and current finger position relative to the reference point and the last reference point.</summary>
|
|||
|
public float GetDeltaRadians(Vector2 referencePoint, Vector2 lastReferencePoint)
|
|||
|
{
|
|||
|
var a = GetLastRadians(lastReferencePoint);
|
|||
|
var b = GetRadians(referencePoint);
|
|||
|
var d = Mathf.Repeat(a - b, Mathf.PI * 2.0f);
|
|||
|
|
|||
|
if (d > Mathf.PI)
|
|||
|
{
|
|||
|
d -= Mathf.PI * 2.0f;
|
|||
|
}
|
|||
|
|
|||
|
return d;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the delta angle between the last and current finger position relative to the reference point.</summary>
|
|||
|
public float GetDeltaDegrees(Vector2 referencePoint)
|
|||
|
{
|
|||
|
return GetDeltaRadians(referencePoint, referencePoint) * Mathf.Rad2Deg;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the delta angle between the last and current finger position relative to the reference point and the last reference point.</summary>
|
|||
|
public float GetDeltaDegrees(Vector2 referencePoint, Vector2 lastReferencePoint)
|
|||
|
{
|
|||
|
return GetDeltaRadians(referencePoint, lastReferencePoint) * Mathf.Rad2Deg;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the distance between the finger and the reference point.</summary>
|
|||
|
public float GetScreenDistance(Vector2 point)
|
|||
|
{
|
|||
|
return Vector2.Distance(ScreenPosition, point);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'GetScreenDistance' value.</summary>
|
|||
|
public float GetScaledDistance(Vector2 point)
|
|||
|
{
|
|||
|
return GetScreenDistance(point) * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the distance between the last finger and the reference point.</summary>
|
|||
|
public float GetLastScreenDistance(Vector2 point)
|
|||
|
{
|
|||
|
return Vector2.Distance(LastScreenPosition, point);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'GetLastScreenDistance' value.</summary>
|
|||
|
public float GetLastScaledDistance(Vector2 point)
|
|||
|
{
|
|||
|
return GetLastScreenDistance(point) * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the distance between the start finger and the reference point.</summary>
|
|||
|
public float GetStartScreenDistance(Vector2 point)
|
|||
|
{
|
|||
|
return Vector2.Distance(StartScreenPosition, point);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This returns a resolution-independent 'GetStartScreenDistance' value.</summary>
|
|||
|
public float GetStartScaledDistance(Vector2 point)
|
|||
|
{
|
|||
|
return GetStartScreenDistance(point) * LeanTouch.ScalingFactor;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the start world position of this finger based on the distance from the camera.</summary>
|
|||
|
public Vector3 GetStartWorldPosition(float distance, Camera camera = null)
|
|||
|
{
|
|||
|
// Make sure the camera exists
|
|||
|
camera = LeanHelper.GetCamera(camera);
|
|||
|
|
|||
|
if (camera != null)
|
|||
|
{
|
|||
|
var point = new Vector3(StartScreenPosition.x, StartScreenPosition.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);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the last world position of this finger based on the distance from the camera.</summary>
|
|||
|
public Vector3 GetLastWorldPosition(float distance, Camera camera = null)
|
|||
|
{
|
|||
|
// Make sure the camera exists
|
|||
|
camera = LeanHelper.GetCamera(camera);
|
|||
|
|
|||
|
if (camera != null)
|
|||
|
{
|
|||
|
var point = new Vector3(LastScreenPosition.x, LastScreenPosition.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);
|
|||
|
}
|
|||
|
|
|||
|
/// <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);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>This will return the change in world position of this finger based on the distance from the camera.</summary>
|
|||
|
public Vector3 GetWorldDelta(float distance, Camera camera = null)
|
|||
|
{
|
|||
|
return GetWorldDelta(distance, distance, camera);
|
|||
|
}
|
|||
|
|
|||
|
/// <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 clear all snapshots for this finger and pool them, count = -1 for all.</summary>
|
|||
|
public void ClearSnapshots(int count = -1)
|
|||
|
{
|
|||
|
// Clear old ones only?
|
|||
|
if (count > 0 && count <= Snapshots.Count)
|
|||
|
{
|
|||
|
for (var i = 0; i < count; i++)
|
|||
|
{
|
|||
|
LeanSnapshot.InactiveSnapshots.Add(Snapshots[i]);
|
|||
|
}
|
|||
|
|
|||
|
Snapshots.RemoveRange(0, count);
|
|||
|
}
|
|||
|
// Clear all?
|
|||
|
else if (count < 0)
|
|||
|
{
|
|||
|
LeanSnapshot.InactiveSnapshots.AddRange(Snapshots);
|
|||
|
|
|||
|
Snapshots.Clear();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>Calling this will instantly store a snapshot of the current finger position.</summary>
|
|||
|
public void RecordSnapshot()
|
|||
|
{
|
|||
|
// Get an unused snapshot and set it up
|
|||
|
var snapshot = LeanSnapshot.Pop();
|
|||
|
|
|||
|
snapshot.Age = Age;
|
|||
|
snapshot.ScreenPosition = ScreenPosition;
|
|||
|
|
|||
|
// Add to list
|
|||
|
Snapshots.Add(snapshot);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|