基于移动端与PC端通用的手指拖动物体实现
需求
移动端的触摸选择,拖动物体根据手指拖动进行移动
想法1
在鼠标点击或手指触摸时记录当前物体的坐标与触摸点与物体的偏移值,鼠标长按时或手指触摸移动时进行更新物体坐标
实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Drag : MonoBehaviour
{
//偏移值
Vector3 m_Offset;
//当前物体对应的屏幕坐标
Vector3 m_TargetScreenVec;
private IEnumerator OnMouseDown()
{
//当前物体对应的屏幕坐标
m_TargetScreenVec = Camera.main.WorldToScreenPoint(transform.position);
//偏移值=物体的世界坐标,减去转化之后的鼠标世界坐标(z轴的值为物体屏幕坐标的z值)
m_Offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, m_TargetScreenVec.z));
//当鼠标左键点击
while (Input.GetMouseButton(0))
{
//当前坐标等于转化鼠标为世界坐标(z轴的值为物体屏幕坐标的z值)+ 偏移量
transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, m_TargetScreenVec.z)) + m_Offset;
//等待固定更新
yield return new WaitForFixedUpdate();
}
}
//为了使这段代码在移动端也能工作,只需要把Input.mousePosition替换成Input.GetTouch(0).position即可
}
想法2
在触摸的阶段,以当前相机的视角根据触摸点的移动量来移动物体,在触摸移动阶段实时更新需要移动物体的坐标。
using UnityEngine;
using UnityEngine.EventSystems;
public class Drag : MonoBehaviour
{
Ray ray;
RaycastHit hit;
bool MoveTag;
private void Update()
{
//鼠标不在UI上,需要在场景中加上EventSystem,可直接随便加个UI自动创建
if (!EventSystem.current.IsPointerOverGameObject())
{
if (Input.touchCount > 0)
{
switch (Input.touches[0].phase)
{
case TouchPhase.Began:
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//射线检测是否需要移动地面
if (Physics.Raycast(ray, out hit))
{
MoveTag = true;
}
else
{
MoveTag = false;
}
break;
case TouchPhase.Moved:
if (MoveTag)
{
transform.Translate(new Vector3(Input.touches[0].deltaPosition.x * Time.deltaTime, 0, Input.touches[0].deltaPosition.y * Time.deltaTime));
}
break;
case TouchPhase.Stationary:
break;
case TouchPhase.Ended:
MoveTag = false;
break;
case TouchPhase.Canceled:
MoveTag = false;
break;
default:
break;
}
}
}
}
}