这是我第一次尝试在Unity中制作带有触摸控件的手机游戏。我基本上可以正常工作了。但是有一个问题,如何清楚地表明滑动不是轻拍?
我在教程中部分发现的代码的工作方式是,注册一个水龙头,我看用户是否在最短时间内静止了触摸屏(在这种情况下为0.05秒)。对于滑动,我查看用户的触摸是否在最小距离范围内移动。
问题在于,由于用户在0.05秒内没有移动手指,所以轻扫的开始通常会记录为轻击。我可以简单地增加注册一次点击的最小静止时间,但这意味着从用户点击屏幕到执行动作之间,游戏会有更多的延迟...
我的问题是否有完美的解决方案?在移动游戏《雷曼历险记》中,水龙头使玩家跳动并滑动即可更改其方向,并且运行十分流畅,当您尝试改变方向时,只有极少数情况下玩家会跳动。我不知道他们是如何工作的。
提前感谢您的时间!
这是我的代码:
public static event Action<SwipeData> OnSwipe = delegate { };
public static event Action OnTap = delegate { };
[Header("Swipe parameters")]
[SerializeField]
bool m_DetectSwipeOnlyAfterRelease;
[SerializeField]
float m_MinDistanceForSwipe;
[Header("Tap parameters")]
[SerializeField]
float m_TapTimeMinThreshold;
private Vector2 m_FingerDownPosition;
private Vector2 m_FingerUpPosition;
private float m_TouchTime;
private bool m_StationaryTouch;
private bool m_TapRegistered;
private bool m_SwipeRegistered;
void Start() {
m_TapRegistered = true;
m_SwipeRegistered = true;
}
void Update() {
if (Input.touchCount == 1) {
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began) {
m_FingerUpPosition = touch.position;
m_FingerDownPosition = touch.position;
m_TouchTime = Time.time;
m_StationaryTouch = true;
m_TapRegistered = false;
m_SwipeRegistered = false;
}
if(!m_SwipeRegistered && touch.phase == TouchPhase.Moved) {
m_StationaryTouch = false;
m_FingerDownPosition = touch.position;
SwipeDirection swipeDirection = DetectSwipe();
// If a swipe was registered
if (!swipeDirection.Equals(SwipeDirection.NONE)) {
// And it was horizontal, we reset the swipe detection
if (swipeDirection.Equals(SwipeDirection.LEFT) || swipeDirection.Equals(SwipeDirection.RIGHT))
m_FingerUpPosition = touch.position;
else
m_SwipeRegistered = true;
}
}
// If the touch was stationary for the min threshold amount of time we register it as a tap
if (m_StationaryTouch && !m_TapRegistered && Time.time - m_TouchTime > m_TapTimeMinThreshold) {
m_TapRegistered = true;
OnTap();
}
if (!m_SwipeRegistered && touch.phase == TouchPhase.Ended && !m_TapRegistered) {
m_FingerDownPosition = touch.position;
DetectSwipe();
}
}
}
private SwipeDirection DetectSwipe() {
if (SwipeDistanceCheckMet()) {
SwipeDirection direction;
if (IsVerticalSwipe()) {
direction = m_FingerDownPosition.y - m_FingerUpPosition.y > 0 ? SwipeDirection.UP : SwipeDirection.DOWN;
SendSwipe(direction);
}
else {
direction = m_FingerDownPosition.x - m_FingerUpPosition.x > 0 ? SwipeDirection.RIGHT : SwipeDirection.LEFT;
SendSwipe(direction);
}
m_FingerUpPosition = m_FingerDownPosition;
return direction;
}
return SwipeDirection.NONE;
}
private bool IsVerticalSwipe() {
return VerticalMovementDistance() > HorizontalMovementDistance();
}
private bool SwipeDistanceCheckMet() {
return VerticalMovementDistance() > m_MinDistanceForSwipe || HorizontalMovementDistance() > m_MinDistanceForSwipe;
}
private float VerticalMovementDistance() {
return Mathf.Abs(m_FingerDownPosition.y - m_FingerUpPosition.y);
}
private float HorizontalMovementDistance() {
return Mathf.Abs(m_FingerDownPosition.x - m_FingerUpPosition.x);
}
private void SendSwipe(SwipeDirection direction) {
SwipeData swipeData = new SwipeData()
{
Direction = direction,
StartPosition = m_FingerDownPosition,
EndPosition = m_FingerUpPosition
};
OnSwipe(swipeData);
}