using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; namespace BF { public class BFFinger { public int index; // 手指索引 public float age; // 手指存活时间 public bool touching; // 是否在触摸屏幕 public bool lastTouching; // 上一帧是否触摸屏幕 public bool hit; // 是否点击屏幕 public int hitCount; // 点击次数 public bool slide; // 是否滑动屏幕 public bool dead; // 手指是否死亡 public float pressure; // 手指压力 public float lastPressure; // 上一帧手指压力 public Vector2 startScreenPos; // 手指出生时屏幕坐标 public Vector2 lastScreenPos; // 手指上一帧屏幕坐标 public Vector2 curScreenPos; // 手指当前屏幕坐标 public bool startOverTargetLayer; // 手指出生时射线是否在target layer上 public Transform startTargetTrans; // 手指出生时射线检测到的transform,没有检测结果为null public bool cantTriggerHit; // 是否不能触发hit事件 public List snapshotList = new List(100); // 手指快照 // 手指出生时所在的target layer public LayerMask StartLayer { get { if (startTargetTrans != null) { return 1 << startTargetTrans.gameObject.layer; } return default; } } public bool IsActive { get { return BFMain.Instance.TouchMgr.fingers.Contains(this); } } public float SnapshotDuration { get { if (snapshotList.Count > 0) { return age - snapshotList[0].age; } else { return 0.0f; } } } public bool IsOverTargetLayer { get { return BFMain.Instance.TouchMgr.PointOverTargetLayer(curScreenPos); } } public Transform TargetTrans { get { return BFMain.Instance.TouchMgr.RaycastFindTrans(curScreenPos); } } public bool Hit { get { return hit && !cantTriggerHit; } } public bool Down { get { return touching == true && lastTouching == false; } } public bool Up { get { return touching == false && lastTouching == true; } } public bool Move { get { return touching == true && curScreenPos != lastScreenPos; } } public Vector2 LastSnapshotScreenDelta { get { var snapshotCount = snapshotList.Count; if (snapshotCount > 0) { var snapshot = snapshotList[snapshotCount - 1]; if (snapshot != null) { return curScreenPos - snapshot.screenPos; } } return Vector2.zero; } } public Vector2 ScreenDelta { get { return curScreenPos - lastScreenPos; } } public Vector2 SlideScreenDelta { get { return curScreenPos - startScreenPos; } } public Ray GetRay(Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { return camera.ScreenPointToRay(curScreenPos); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component"); } return default; } public Ray GetStartRay(Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { return camera.ScreenPointToRay(startScreenPos); } else { Debug.LogError("Failed to find camera. Either tag your cameras MainCamera, or set one in this component"); } return default; } public Vector2 GetSnapshotScreenDelta(float deltaTime) { return curScreenPos - GetSnapshotScreenPosition(age - deltaTime); } public Vector2 GetSnapshotScreenPosition(float targetAge) { var pos = curScreenPos; BFFingerSnapshot.TryGetScreenPos(snapshotList, targetAge, ref pos); return pos; } public Vector3 GetSnapshotWorldPosition(float targetAge, float distance, Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { var screenPos = GetSnapshotScreenPosition(targetAge); var point = new Vector3(screenPos.x, screenPos.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 Vector3.zero; } public float GetRadians(Vector2 referencePoint) { return Mathf.Atan2(curScreenPos.x - referencePoint.x, curScreenPos.y - referencePoint.y); } public float GetDegrees(Vector2 referencePoint) { return GetRadians(referencePoint) * Mathf.Rad2Deg; } public float GetLastRadians(Vector2 referencePoint) { return Mathf.Atan2(lastScreenPos.x - referencePoint.x, lastScreenPos.y - referencePoint.y); } public float GetLastDegrees(Vector2 referencePoint) { return GetLastRadians(referencePoint) * Mathf.Rad2Deg; } public float GetDeltaRadians(Vector2 referencePoint) { return GetDeltaRadians(referencePoint, referencePoint); } 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; } public float GetDeltaDegrees(Vector2 referencePoint) { return GetDeltaRadians(referencePoint) * Mathf.Rad2Deg; } public float GetDeltaDegrees(Vector2 referencePoint, Vector2 lastReferencePoint) { return GetDeltaRadians(referencePoint, lastReferencePoint) * Mathf.Rad2Deg; } public float GetScreenDistance(Vector2 point) { return Vector2.Distance(curScreenPos, point); } public float GetLastScreenDistance(Vector2 point) { return Vector2.Distance(lastScreenPos, point); } public float GetStartScreenDistance(Vector2 point) { return Vector2.Distance(startScreenPos, point); } public Vector3 GetStartWorldPosition(float distance, Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { var point = new Vector3(startScreenPos.x, startScreenPos.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 Vector3.zero; } public Vector3 GetLastWorldPosition(float distance, Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { var point = new Vector3(lastScreenPos.x, lastScreenPos.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 Vector3.zero; } public Vector3 GetWorldPosition(float distance, Camera camera = null) { if (camera == null) { camera = Camera.main; } if (camera != null) { var point = new Vector3(curScreenPos.x, curScreenPos.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 Vector3.zero; } public Vector3 GetWorldDelta(float distance, Camera camera = null) { return GetWorldDelta(distance, distance, camera); } public Vector3 GetWorldDelta(float lastDistance, float distance, Camera camera = null) { if (camera == null) { camera = Camera.main; } 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 Vector3.zero; } public void ClearSnapshots(int count = -1) { if (count > 0 && count <= snapshotList.Count) { for (int i = 0; i < count; i++) { BFFingerSnapshot.Push(snapshotList[i]); } snapshotList.RemoveRange(0, count); } else if (count < 0) { BFFingerSnapshot.InactiveSnapshots.AddRange(snapshotList); snapshotList.Clear(); } } public void RecordSnapshot() { var snapshot = BFFingerSnapshot.Pop(); snapshot.age = age; snapshot.screenPos = curScreenPos; snapshotList.Add(snapshot); } } }