c# - Unity:使用 TouchPhase.Moved 时如何停止读取第一次触摸
问题描述
我有两个脚本一个是播放器控制器:
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);
}
这两个都很好:我可以通过点击移动我的角色并在滑动时很好地旋转相机,唯一的问题是当我滑动旋转时,它会记录触摸的开始并开始移动。我将如何避免这种情况?
解决方案
而不是在触摸开始时移动,您只能在触摸结束时移动,并且在触摸期间触摸位置没有太大变化。
如果正在触摸并且位置变化超过一点阈值,则将其解释为滑动并在触摸结束时跳过调用目标代码块。
// 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;
}
}
推荐阅读
- c++ - 错误:命名空间“std”中的“mutex”未命名类型
- java - HandlerInterceptor 不适用于 Api Gateway Zuul
- javascript - javascript中的数组方法
- python-3.x - 如何从 Raspberry Pi Zero 向 PC 发送实时传感器数据?
- c# - 如何从 Unity 中的另一个脚本引用枚举
- facebook - 如何在颤动中将文本分享到 Facebook 的新闻提要
- ios - 与单个大型网络调用相比,小型网络调用的成本是多少?
- laravel - laravel - livewire 全页组件
- visual-studio - 启动 Azure Function 时,不要自动启动模拟器等
- python - 在熊猫数据框中添加差异行