增加多指触控支持

This commit is contained in:
shenjianxing 2025-03-25 15:22:32 +08:00
parent 292e1f0a3d
commit 08fc6b4b02

View File

@ -43,6 +43,7 @@ public class Show3DCamera : MonoBehaviour
Transform target; Transform target;
Vector3 targetPosition; Vector3 targetPosition;
Vector3 targetRotate; Vector3 targetRotate;
private float prevTouchDistance; // 存储上一帧双指距离
private void Awake() private void Awake()
{ {
instance = this; instance = this;
@ -124,28 +125,43 @@ public class Show3DCamera : MonoBehaviour
UpdateCameraPosition(-1); UpdateCameraPosition(-1);
} }
void Update() void Update()
{ {
if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false) if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false)
{ {
// 优先处理三指操作
if (HandleThreeFingerDrag()) return;
bool isTouching = Input.touchCount > 0;
// 新增:在旋转前先处理双指缩放
if (Input.GetMouseButtonDown(0)) bool isZooming = false;
if (isTouching && Input.touchCount == 2)
{
HandleTouchZoom();
isZooming = true; // 标记正在缩放
}
// 处理触摸开始(排除双指情况)
if (isTouching && Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
mouseDownPosition = Input.GetTouch(0).position;
}
}
// 处理鼠标按下
else if (Input.GetMouseButtonDown(0))
{ {
// 记录鼠标按下时的位置
mouseDownPosition = Input.mousePosition; mouseDownPosition = Input.mousePosition;
} }
// 按住鼠标左键时旋转相机 // 修改后的旋转条件(排除缩放状态)
if (Input.GetMouseButton(0)) if (!isZooming && (isTouching ? (Input.GetTouch(0).phase == TouchPhase.Moved) : Input.GetMouseButton(0)))
{
// 计算鼠标按下和抬起位置之间的距离
float distance = Vector2.Distance(mouseDownPosition, Input.mousePosition);
if (distance > 1f)
{ {
// 移除距离判断直接响应
RotateCamera(); RotateCamera();
} }
}
// 鼠标滚轮缩放 // 鼠标滚轮缩放
float scroll = Input.GetAxis("Mouse ScrollWheel"); float scroll = Input.GetAxis("Mouse ScrollWheel");
@ -154,7 +170,6 @@ public class Show3DCamera : MonoBehaviour
ZoomCamera(scroll); ZoomCamera(scroll);
} }
// 按住鼠标右键时移动目标点 // 按住鼠标右键时移动目标点
if (Input.GetMouseButton(1)) if (Input.GetMouseButton(1))
{ {
@ -163,6 +178,91 @@ public class Show3DCamera : MonoBehaviour
DetectHoveredObject(); DetectHoveredObject();
} }
} }
// 唯一的三指处理方法返回bool用于阻断其他操作
private bool HandleThreeFingerDrag()
{
if (Input.touchCount == 5)
{
// 计算三个触点的平均移动量
Vector2 totalDelta = Vector2.zero;
foreach (Touch t in Input.touches)
{
totalDelta += t.deltaPosition;
}
Vector2 delta = totalDelta / 3f;
// DPI自适应处理
float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f;
float sensitivity = moveSpeed * 0.1f / dpiScale;
// 应用移动阈值2像素
if (delta.magnitude > 2f)
{
// 调用修改后的移动方法
MoveTarget(delta.x * sensitivity, delta.y * sensitivity);
}
// 阻断其他触摸操作
return true;
}
return false;
}
// 新增双指缩放处理方法
// 类变量区添加
private float zoomSmoothVelocity; // 平滑速度缓存
[SerializeField] private float zoomSmoothTime = 0.1f; // 缩放平滑时间
private void HandleTouchZoom()
{
if (Input.touchCount == 2)
{
Touch touch0 = Input.GetTouch(0);
Touch touch1 = Input.GetTouch(1);
// 当双指操作时重置旋转相关变量
if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began)
{
yaw = transform.eulerAngles.y; // 保持当前旋转角度
pitch = transform.eulerAngles.x;
mouseDownPosition = Vector2.zero;
}
Vector2 touch0Pos = touch0.position;
Vector2 touch1Pos = touch1.position;
float currentDistance = Vector2.Distance(touch0Pos, touch1Pos);
// DPI自适应计算
float dpi = Screen.dpi == 0 ? 200 : Screen.dpi;
float zoomFactor = 0.01f * (200 / dpi); // 基准DPI为200
if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began)
{
prevTouchDistance = currentDistance;
zoomSmoothVelocity = 0; // 重置平滑速度
}
else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved)
{
float deltaDistance = currentDistance - prevTouchDistance;
// 仅触摸缩放使用平滑
float targetDistance = distance - deltaDistance * zoomFactor;
targetDistance = Mathf.Clamp(targetDistance, distanceMin, distanceMax);
distance = Mathf.SmoothDamp(
distance,
targetDistance,
ref zoomSmoothVelocity,
zoomSmoothTime
);
offset = new Vector3(0, 0, -distance);
UpdateCameraPosition();
prevTouchDistance = currentDistance;
}
}
}
// 检测鼠标悬停的物体 // 检测鼠标悬停的物体
public void DetectHoveredObject() public void DetectHoveredObject()
@ -252,11 +352,15 @@ public class Show3DCamera : MonoBehaviour
} }
// 移动目标点 // 修改后的移动方法(统一处理输入源)
private void MoveTarget() private void MoveTarget(float mouseX = 0, float mouseY = 0)
{ {
float mouseX = Input.GetAxis("Mouse X") * moveSpeed; // 自动判断输入源
float mouseY = Input.GetAxis("Mouse Y") * moveSpeed; if (Mathf.Approximately(mouseX, 0) && Mathf.Approximately(mouseY, 0))
{
mouseX = Input.GetAxis("Mouse X") * moveSpeed;
mouseY = Input.GetAxis("Mouse Y") * moveSpeed;
}
transform.Translate(new Vector3(-mouseX, -mouseY, 0)); transform.Translate(new Vector3(-mouseX, -mouseY, 0));
targetPos += new Vector3(-mouseX, -mouseY, 0); targetPos += new Vector3(-mouseX, -mouseY, 0);
@ -270,31 +374,44 @@ public class Show3DCamera : MonoBehaviour
UpdateCameraPosition(); UpdateCameraPosition();
} }
// 旋转相机 // 修改RotateCamera方法
private void RotateCamera() private void RotateCamera()
{ {
// 获取鼠标移动量 // 优先使用触摸输入
float mouseX = Input.GetAxis("Mouse X") * rotateSpeed; float deltaX = 0, deltaY = 0;
float mouseY = Input.GetAxis("Mouse Y") * rotateSpeed;
// 触屏处理
if (Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
deltaX = touch.deltaPosition.x;
deltaY = touch.deltaPosition.y;
}
// 鼠标处理
else
{
deltaX = Input.GetAxis("Mouse X") * 10; // 保持原有灵敏度
deltaY = Input.GetAxis("Mouse Y") * 10;
}
// 应用DPI缩放关键
float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f;
deltaX *= rotateSpeed * Time.deltaTime / dpiScale;
deltaY *= rotateSpeed * Time.deltaTime / dpiScale;
switch (type) switch (type)
{ {
case RotationType.Orbit: case RotationType.Orbit:
yaw += deltaX;
// 更新偏航角和俯仰角 pitch -= deltaY;
yaw += mouseX; pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
pitch -= mouseY; // 注意:鼠标 Y 轴移动方向与俯仰角相反
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y); // 限制俯仰角范围
// 更新相机位置
UpdateCameraPosition(); UpdateCameraPosition();
break; break;
case RotationType.Spherical: case RotationType.Spherical:
// 完全自由的旋转包含X/Y/Z三个轴向 target.Rotate(Vector3.up, deltaX, Space.World);
target.Rotate(Vector3.up, mouseX, Space.World); // 水平方向世界Y轴旋转 target.Rotate(Vector3.right, -deltaY, Space.Self);
target.Rotate(Vector3.right, -mouseY, Space.Self); // 垂直方向本地X轴旋转
break; break;
} }
} }
public void ChangeMode(RotationType type) public void ChangeMode(RotationType type)