Unity:使用TouchPhase时如何停止读取第一触摸

时间:2018-11-30 02:34:46

标签: c# unity3d mobile

我有两个脚本,一个是具有此功能的播放器控制器:

void Update () {
   if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
    {


        Touch touch = Input.GetTouch(0);
        Ray ray = cam.ScreenPointToRay(touch.position);
        RaycastHit hit;

        if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
        {
            return;
        }


        if (Physics.Raycast(ray, out hit, 100))
        {

            Interactable interactable = hit.collider.GetComponent<Interactable>();
             if (interactable != null)
             {
                SetFocus(interactable);
             }
             else
             {
                motor.MoveToPoint(hit.point);

                RemoveFocus();
            }

        }
    }
}       

然后我的相机脚本是:

void Update()
{
    currentZoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
    currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);

    currentYaw -= Input.GetAxis("Horizontal") * yawSpeed * Time.deltaTime;
    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
    {
        Vector2 touchDirection = Input.GetTouch(0).deltaPosition;
        if (touchDirection.x > minSwipe || touchDirection.x < -minSwipe)
        {
            currentYaw -= touchDirection.x * yawSpeed / mobileYawReduction * Time.deltaTime;
        }

    }
}

// Update is called once per frame
void LateUpdate () {
    transform.position = target.position - offset * currentZoom;
    transform.LookAt(target.position + Vector3.up * pitch);

    transform.RotateAround(target.position, Vector3.up, currentYaw);
}

这两种方法都可以正常工作:轻扫时,我可以轻点移动我的角色并很好地旋转相机,唯一的问题是,当我轻扫旋转时,它记录了触摸的开始并开始移动。我将如何避免这种情况?

1 个答案:

答案 0 :(得分:0)

只能在触摸结束时移动,而在触摸过程中触摸位置不会改变很多,而不是在触摸开始时移动。

如果正在触摸并且位置变化超过一个小阈值,则将其解释为轻扫,并在触摸结束时跳过对目标代码块的调用。

// if movement was greater than interpret as swipe 
public float swipeThreshold = 0.01;

Vector2 startPosition ;
float movedDistance;

Touch touch;

void Update () 
{
    if (Input.touchCount <= 0) return;

    switch(Input.GetTouch(0).phase)
    {
        case TouchPhase.Began:
            // On begin only save the start position

            touch = Input.GetTouch(0);

            if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                return;
            }

            startPosition = touch.position;
            movedDistance = 0;
            break;

        case TouchPhase.Moved:
            // if moving check how far you moved

            movedDistance = Vector2.Distance(touch.position, startPosition );
            break;

        case TouchPhase.Ended:
            // on end of touch (like button up) check the distance
            // if you swiped -> moved more than swipeThreshold
            // do nothing

            if(movedDistance > swipeThreshold) break;

            Ray ray = cam.ScreenPointToRay(touch.position);
            RaycastHit hit;
            if (!Physics.Raycast(ray, out hit, 100)) break;

            Interactable interactable = hit.collider.GetComponent<Interactable>();
            if (interactable != null)
            {
                SetFocus(interactable);
            }
            else
            {
                motor.MoveToPoint(hit.point);
                RemoveFocus();
            }
            break;

        default:
            break;
    }
}
我会向摄像机脚本添加相同的阈值以保持一致。在两者之间以某种方式共享此阈值(甚至从另一个脚本获取该阈值),或者只是将其设置为相同的值

public float swipeThreshold = 0.01;

Vector2 startPosition;

void Update()
{
    currentZoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
    currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);

    currentYaw -= Input.GetAxis("Horizontal") * yawSpeed * Time.deltaTime;

    if (Input.touchCount <= 0) return;

    switch(Input.GetTouch(0).phase)
    {
        case TouchPhase.Began:
            startPosition = Input.GetTouch(0).position;
            break;

        case TouchPhase.Moved:
            // if yet not moved enough do nothing
            var movedDistance = Vector2.Distance(Input.GetTouch(0).position, startPosition);
            if (movedDistance <= swipeThreshold) break;

            Vector2 touchDirection = Input.GetTouch(0).deltaPosition;
            if (touchDirection.x > minSwipe || touchDirection.x < -minSwipe)
            {
                currentYaw -= touchDirection.x * yawSpeed / mobileYawReduction * Time.deltaTime;
            }
            break;

        default:
            break;
    }
}