323 lines
8.9 KiB
C#
323 lines
8.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using Game;
|
|
using Game.Pool;
|
|
using UnityEngine;
|
|
|
|
public enum TouchType
|
|
{
|
|
None, // 无状态输入
|
|
单击, // 超过0.3s未再次点击判定为单击
|
|
双击, // 第二次点击时间为0.3s内,判定为双击
|
|
长按, // 长按某个位置时间超过1.5s,判定为长按
|
|
放大, // 双指内掐
|
|
缩小, //双指外扩
|
|
由左向右滑动,
|
|
由右向左滑动,
|
|
由后向前滑动,
|
|
由前向后滑动,
|
|
}
|
|
|
|
public interface ITouchManager
|
|
{
|
|
TouchType TouchType { get; }
|
|
}
|
|
|
|
public class TouchManager : ManagerBase, ITouchManager
|
|
{
|
|
private TouchType oldType;
|
|
private TouchType touchType;
|
|
public TouchType TouchType => this.touchType;
|
|
|
|
private float currentDoubleTime;
|
|
private float currentLongTime;
|
|
private float maxDoubleTime = 0.3f;
|
|
private float maxLongTime = 1.5f;
|
|
private bool isDoubleStarting;
|
|
private bool isLongStarting;
|
|
|
|
private float f = 5f;
|
|
|
|
// events
|
|
public Action OnClick; // 单击
|
|
public Action OnDoubleClick; // 双击
|
|
public Action OnLongClick; // 长按
|
|
public Action OnBlowUp; // 放大
|
|
public Action OnBlowDown; // 缩小
|
|
public Action OnLeftToRight; // 由左向右滑动
|
|
public Action OnRightToLeft; // 由右向左滑动
|
|
public Action OnFrontToBack; // 由前向后滑动
|
|
public Action OnBackToFront; // 由后向前滑动
|
|
|
|
private void Start()
|
|
{
|
|
this.isDoubleStarting = false;
|
|
this.isLongStarting = false;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Input.touchCount == 1)
|
|
{
|
|
this.One();
|
|
}
|
|
else if (Input.touchCount == 2)
|
|
{
|
|
this.IsEnlarge();
|
|
}
|
|
}
|
|
|
|
private string oldId;
|
|
private string newId;
|
|
private string currentId;
|
|
|
|
void One()
|
|
{
|
|
Touch touch0 = Input.GetTouch(0);
|
|
var vector2 = touch0.deltaPosition;
|
|
|
|
switch (touch0.phase)
|
|
{
|
|
case TouchPhase.Began:
|
|
this.newId = Guid.NewGuid().ToString();
|
|
this.currentId = this.newId;
|
|
break;
|
|
case TouchPhase.Moved:
|
|
if (this.currentId != this.newId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (vector2.x > f)
|
|
ChangeState(TouchType.由左向右滑动);
|
|
else if (vector2.x < -f)
|
|
ChangeState(TouchType.由右向左滑动);
|
|
|
|
if (vector2.y > f)
|
|
ChangeState(TouchType.由前向后滑动);
|
|
else if (vector2.y < -f)
|
|
ChangeState(TouchType.由后向前滑动);
|
|
|
|
break;
|
|
case TouchPhase.Stationary:
|
|
break;
|
|
case TouchPhase.Ended:
|
|
this.oldId = this.newId;
|
|
ChangeState(TouchType.None);
|
|
break;
|
|
case TouchPhase.Canceled:
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
if (vector2 == Vector2.zero) // 使用实现
|
|
{
|
|
if (touch0.phase == TouchPhase.Began && !this.isDoubleStarting)
|
|
{
|
|
this.isDoubleStarting = true;
|
|
|
|
// if (this.Double != null)
|
|
// StopCoroutine(this.Double);
|
|
// Double = this.UpdateDouble();
|
|
// StartCoroutine(this.Double);
|
|
|
|
|
|
if (this.doubleToken != null && !this.doubleToken.isDispose)
|
|
{
|
|
this.doubleToken.Cancel();
|
|
}
|
|
|
|
this.doubleToken = TokenPool.GetToken();
|
|
this.Double = UpdateDouble(this.doubleToken);
|
|
this.Double.Forget();
|
|
}
|
|
|
|
if (touch0.phase == TouchPhase.Began && !this.isLongStarting)
|
|
{
|
|
this.isLongStarting = true;
|
|
|
|
// if (this.Long != null)
|
|
// StopCoroutine(this.Long);
|
|
// Long = this.UpdateLong();
|
|
// StartCoroutine(this.Long);
|
|
|
|
if (this.longToken != null && !this.longToken.isDispose)
|
|
{
|
|
this.longToken.Cancel();
|
|
}
|
|
|
|
this.longToken = TokenPool.GetToken();
|
|
this.Long = UpdateLong(this.longToken);
|
|
this.Long.Forget();
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: add
|
|
private bool isFinish;
|
|
private UniTask Double;
|
|
private ITokenInfo doubleToken;
|
|
private UniTask Long;
|
|
private ITokenInfo longToken;
|
|
|
|
async UniTask UpdateDouble(ITokenInfo tokenInfo)
|
|
{
|
|
if (this.isFinish)
|
|
this.isFinish = false;
|
|
|
|
string tmpId = this.currentId;
|
|
this.currentDoubleTime = 0;
|
|
while (this.currentDoubleTime < this.maxDoubleTime)
|
|
{
|
|
if (tokenInfo.isDispose)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await UniTask.Yield();
|
|
this.currentDoubleTime += Time.deltaTime;
|
|
|
|
if (Input.touchCount == 1 && tmpId != this.currentId && Input.GetTouch(0).phase == TouchPhase.Ended)
|
|
{
|
|
// 双击
|
|
ChangeState(TouchType.双击);
|
|
this.isFinish = true;
|
|
this.isDoubleStarting = false;
|
|
tokenInfo.Dispose();
|
|
return;
|
|
}
|
|
|
|
if (this.isFinish)
|
|
{
|
|
this.isDoubleStarting = false;
|
|
tokenInfo.Cancel();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (tmpId == this.currentId)
|
|
{
|
|
if (!this.isFinish && Input.touchCount == 0)
|
|
{
|
|
ChangeState(TouchType.单击);
|
|
this.isFinish = true;
|
|
}
|
|
}
|
|
|
|
this.isDoubleStarting = false;
|
|
tokenInfo.Dispose();
|
|
// 双击不成立
|
|
}
|
|
|
|
async UniTask UpdateLong(ITokenInfo tokenInfo)
|
|
{
|
|
if (this.isFinish)
|
|
this.isFinish = false;
|
|
|
|
this.currentLongTime = 0;
|
|
while (this.currentLongTime < this.maxLongTime)
|
|
{
|
|
await UniTask.Yield();
|
|
this.currentLongTime += Time.deltaTime;
|
|
|
|
if (this.isFinish)
|
|
{
|
|
tokenInfo.Cancel();
|
|
return;
|
|
}
|
|
|
|
if (Input.touchCount == 0 || Input.GetTouch(0).phase != TouchPhase.Stationary)
|
|
{
|
|
this.touchType = TouchType.None;
|
|
isLongStarting = false;
|
|
tokenInfo.Dispose();
|
|
return;
|
|
}
|
|
}
|
|
|
|
while (Input.GetTouch(0).phase == TouchPhase.Ended)
|
|
{
|
|
await UniTask.Yield();
|
|
}
|
|
|
|
if (!this.isFinish)
|
|
{
|
|
ChangeState(TouchType.长按);
|
|
this.isLongStarting = false;
|
|
this.isFinish = true;
|
|
}
|
|
|
|
tokenInfo.Dispose();
|
|
}
|
|
|
|
private Vector2 old1;
|
|
private Vector2 old2;
|
|
|
|
void IsEnlarge()
|
|
{
|
|
Touch touch0 = Input.GetTouch(0);
|
|
Touch touch1 = Input.GetTouch(1);
|
|
Vector2 new1 = touch0.position;
|
|
Vector2 new2 = touch1.position;
|
|
|
|
float length1 = Mathf.Sqrt((old1.x - old2.x) * (old1.x - old2.x) + (old1.y - old2.y) * (old1.y - old2.y));
|
|
float length2 = Mathf.Sqrt((new1.x - new2.x) * (new1.x - new2.x) + (new1.y - new2.y) * (new1.y - new2.y));
|
|
if (length1 < length2)
|
|
ChangeState(TouchType.放大);
|
|
else if (length1 > length2)
|
|
ChangeState(TouchType.缩小);
|
|
else
|
|
ChangeState(TouchType.None);
|
|
|
|
this.old1 = new1;
|
|
this.old2 = new2;
|
|
}
|
|
|
|
private void ChangeState(TouchType newType)
|
|
{
|
|
this.oldType = this.touchType;
|
|
this.touchType = newType;
|
|
FireEvent(newType);
|
|
}
|
|
|
|
void FireEvent(TouchType newType)
|
|
{
|
|
switch (newType)
|
|
{
|
|
case TouchType.None:
|
|
break;
|
|
case TouchType.单击:
|
|
this.OnClick?.Invoke();
|
|
break;
|
|
case TouchType.双击:
|
|
this.OnDoubleClick?.Invoke();
|
|
break;
|
|
case TouchType.长按:
|
|
this.OnLongClick?.Invoke();
|
|
break;
|
|
case TouchType.放大:
|
|
this.OnBlowUp?.Invoke();
|
|
break;
|
|
case TouchType.缩小:
|
|
this.OnBlowDown?.Invoke();
|
|
break;
|
|
case TouchType.由左向右滑动:
|
|
this.OnLeftToRight?.Invoke();
|
|
break;
|
|
case TouchType.由右向左滑动:
|
|
this.OnRightToLeft?.Invoke();
|
|
break;
|
|
case TouchType.由后向前滑动:
|
|
this.OnBackToFront?.Invoke();
|
|
break;
|
|
case TouchType.由前向后滑动:
|
|
this.OnFrontToBack?.Invoke();
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException(nameof(newType), newType, null);
|
|
}
|
|
}
|
|
} |