354 lines
11 KiB
C#
354 lines
11 KiB
C#
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<BFFingerSnapshot> snapshotList = new List<BFFingerSnapshot>(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);
|
||
}
|
||
}
|
||
} |