我有两个脚本,一个是具有此功能的播放器控制器:
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);
}
这两种方法都可以正常工作:轻扫时,我可以轻点移动我的角色并很好地旋转相机,唯一的问题是,当我轻扫旋转时,它记录了触摸的开始并开始移动。我将如何避免这种情况?
答案 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;
}
}