diff --git a/Assets/Scripts/Item/Show3DCamera.cs b/Assets/Scripts/Item/Show3DCamera.cs index a4d7f7d9..166fe3e7 100644 --- a/Assets/Scripts/Item/Show3DCamera.cs +++ b/Assets/Scripts/Item/Show3DCamera.cs @@ -31,6 +31,8 @@ public class Show3DCamera : MonoBehaviour private Vector2 mouseDownPosition; // 记录鼠标按下时的位置 + private bool isDoubleTouching = false; // 记录双指操作状态 + private bool isZooming = false; // 记录双指缩放状态 public enum RotationType { @@ -44,6 +46,10 @@ public class Show3DCamera : MonoBehaviour Vector3 targetPosition; Vector3 targetRotate; private float prevTouchDistance; // 存储上一帧双指距离 + + // 新增:跟踪当前旋转状态 + private Quaternion currentRotation; + private void Awake() { instance = this; @@ -59,6 +65,7 @@ public class Show3DCamera : MonoBehaviour gameObject.SetActive(false); #endif } + private void OnLockEvent(OnLock islock) { this.lockMove = islock.isLock; @@ -77,16 +84,8 @@ public class Show3DCamera : MonoBehaviour this.targetRotate = target.eulerAngles; yaw = 0; pitch = 0; - // 初始化相机位置 this.inputRect = inputRect; this.targetPos = target.transform.position; - //this.rotateSpeed = rotateSpeed; - //this.moveSpeed = moveSpeed; - //this.distance = distance; - //this.distanceMin = distanceMin; - //this.distanceMax = distanceMax; - //this.pitchMinMax = new Vector2(pitchMin, pitchMax); - // 初始化相机位置 offset = new Vector3(0, 0, -distance); if (isRenderTexture) @@ -97,11 +96,12 @@ public class Show3DCamera : MonoBehaviour { self.targetTexture = null; } + + // 初始化旋转状态 + currentRotation = Quaternion.Euler(pitch, yaw, 0); UpdateCameraPosition(moveTime); } - - public void ResetCamera(Transform target, RectTransform inputRect = null, bool isRenderTexture = false) { if (target == null) @@ -114,10 +114,8 @@ public class Show3DCamera : MonoBehaviour this.targetRotate = target.eulerAngles; yaw = 0; pitch = 0; - // 初始化相机位置 this.inputRect = inputRect; this.targetPos = target.transform.position; - // 初始化相机位置 offset = new Vector3(0, 0, -distance); if (isRenderTexture) @@ -128,51 +126,76 @@ public class Show3DCamera : MonoBehaviour { self.targetTexture = null; } + + // 重置旋转状态 + currentRotation = Quaternion.Euler(pitch, yaw, 0); UpdateCameraPosition(-1); } - void Update() { if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false) { // 优先处理三指操作 if (HandleThreeFingerDrag()) return; + bool isTouching = Input.touchCount > 0; - // 新增:在旋转前先处理双指缩放 - bool isZooming = false; + // 处理双指缩放 if (isTouching && Input.touchCount == 2) { HandleTouchZoom(); - isZooming = true; // 标记正在缩放 + isZooming = true; + isDoubleTouching = true; + return; + } + else if (Input.touchCount == 0) + { + isDoubleTouching = false; + isZooming = false; } + bool shouldRotate = false; // 处理触摸开始(排除双指情况) - if (isTouching && Input.touchCount == 1) + if (isTouching && Input.touchCount == 1 && !isDoubleTouching) { if (Input.GetTouch(0).phase == TouchPhase.Began) { mouseDownPosition = Input.GetTouch(0).position; + + // 记录当前旋转状态 + if (type == RotationType.Orbit) + { + currentRotation = Quaternion.Euler(pitch, yaw, 0); + } + } + if (Input.GetTouch(0).phase == TouchPhase.Moved) + { + float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition); + shouldRotate = dragDistance > DRAG_THRESHOLD; } } // 处理鼠标按下 - else if (Input.GetMouseButtonDown(0)) + else if (Input.GetMouseButtonDown(0) && !isDoubleTouching) { mouseDownPosition = Input.mousePosition; + + // 记录当前旋转状态 + if (type == RotationType.Orbit) + { + currentRotation = Quaternion.Euler(pitch, yaw, 0); + } } - bool shouldRotate = false; - if (Input.GetMouseButton(0)) + if (Input.GetMouseButton(0) && !isDoubleTouching) { - // 使用现有参数计算拖拽距离 float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition); shouldRotate = dragDistance > DRAG_THRESHOLD; } - // 修改后的旋转条件(排除缩放状态) - if (!isZooming && (isTouching ? (Input.GetTouch(0).phase == TouchPhase.Moved) : shouldRotate)) + + // 旋转相机 + if (!isZooming && shouldRotate) { - RotateCamera(); } @@ -188,13 +211,15 @@ public class Show3DCamera : MonoBehaviour { MoveTarget(); } + DetectHoveredObject(); } } + // 唯一的三指处理方法(返回bool用于阻断其他操作) private bool HandleThreeFingerDrag() { - if (Input.touchCount == 5) + if (Input.touchCount == 3) { // 计算三个触点的平均移动量 Vector2 totalDelta = Vector2.zero; @@ -221,24 +246,13 @@ public class Show3DCamera : MonoBehaviour 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; @@ -246,37 +260,26 @@ public class Show3DCamera : MonoBehaviour // DPI自适应计算 float dpi = Screen.dpi == 0 ? 200 : Screen.dpi; - float zoomFactor = 0.01f * (200 / dpi); // 基准DPI为200 + float zoomFactor = 0.01f * (200 / dpi); 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(); - + // 添加判断:如果双指距离变化小于某个阈值,则不进行缩放操作 + if (Mathf.Abs(deltaDistance) > 1f) + { + float scroll = deltaDistance * zoomFactor; + ZoomCamera(scroll); + } prevTouchDistance = currentDistance; } } } - // 检测鼠标悬停的物体 public void DetectHoveredObject() { @@ -292,29 +295,21 @@ public class Show3DCamera : MonoBehaviour RaycastHit raycastHit; if (Physics.Raycast(ray, out raycastHit)) { - //Debug.Log(raycastHit.transform.name); obj = raycastHit.transform.gameObject; - - // 如果击中的物体与上一次击中的物体不同,表示射线进入了新物体 if (obj != lastHitObject) { - // 触发进入事件 OnMouseEnterObj(obj); - // 如果上一次击中的物体不为空,触发离开事件 if (lastHitObject != null && lastHitObject != obj) { OnMouseExitObj(lastHitObject); - // 更新上一次击中的物体 lastHitObject = obj; } - } } else { - // 如果射线没有击中任何物体,且上一次击中的物体不为空,触发离开事件 if (lastHitObject != null) { OnMouseExitObj(lastHitObject); @@ -323,13 +318,11 @@ public class Show3DCamera : MonoBehaviour } } - /// /// 聚焦某个物体 /// public void FocusObj(Vector3 target, float distance = 1f, float moveTime = -1) { - // 可以根据需要调整这个距离 Vector3 cameraPos = target - transform.forward * distance; targetPos = target; @@ -361,13 +354,11 @@ public class Show3DCamera : MonoBehaviour { tip.OnExit(); } - } // 修改后的移动方法(统一处理输入源) private void MoveTarget(float mouseX = 0, float mouseY = 0) { - // 自动判断输入源 if (Mathf.Approximately(mouseX, 0) && Mathf.Approximately(mouseY, 0)) { mouseX = Input.GetAxis("Mouse X") * moveSpeed; @@ -377,11 +368,12 @@ public class Show3DCamera : MonoBehaviour transform.Translate(new Vector3(-mouseX, -mouseY, 0)); targetPos += new Vector3(-mouseX, -mouseY, 0); } + // 缩放相机 private void ZoomCamera(float scroll) { - distance -= scroll * 5f; // 调整缩放速度 - distance = Mathf.Clamp(distance, distanceMin, distanceMax); // 限制距离范围 + distance -= scroll * 5f; + distance = Mathf.Clamp(distance, distanceMin, distanceMax); offset = new Vector3(0, 0, -distance); UpdateCameraPosition(); } @@ -389,7 +381,6 @@ public class Show3DCamera : MonoBehaviour // 修改RotateCamera方法 private void RotateCamera() { - // 优先使用触摸输入 float deltaX = 0, deltaY = 0; // 触屏处理 @@ -402,14 +393,13 @@ public class Show3DCamera : MonoBehaviour // 鼠标处理 else { - deltaX = Input.GetAxis("Mouse X") * 10; // 保持原有灵敏度 + deltaX = Input.GetAxis("Mouse X") * 10; deltaY = Input.GetAxis("Mouse Y") * 10; - // 当累计移动量超过阈值时才生效 if (Mathf.Abs(deltaX) < DRAG_THRESHOLD && Mathf.Abs(deltaY) < DRAG_THRESHOLD) return; } - // 应用DPI缩放(关键!) + // 应用DPI缩放 float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f; deltaX *= rotateSpeed * Time.deltaTime / dpiScale; deltaY *= rotateSpeed * Time.deltaTime / dpiScale; @@ -440,24 +430,36 @@ public class Show3DCamera : MonoBehaviour // 更新相机位置和朝向 private void UpdateCameraPosition(float moveTime = -1) { - // 计算旋转后的偏移量 - Quaternion rotation = Quaternion.Euler(pitch, yaw, 0); - Vector3 rotatedOffset = rotation * offset; - // 更新相机位置 - if (moveTime != -1) + if (type == RotationType.Orbit) { - transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () => - // 相机始终朝向目标点 - transform.LookAt(targetPos); - } - else - { - transform.position = targetPos + rotatedOffset; - // 相机始终朝向目标点 - transform.LookAt(targetPos); - } + // 使用四元数计算旋转后的偏移量 + Quaternion rotation = Quaternion.Euler(pitch, yaw, 0); + Vector3 rotatedOffset = rotation * offset; + if (moveTime != -1) + { + transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () => + transform.LookAt(targetPos); + } + else + { + transform.position = targetPos + rotatedOffset; + transform.LookAt(targetPos); + } + } + else if (type == RotationType.Spherical) + { + // 球形模式下的相机跟随 + if (moveTime != -1) + { + transform.DOMove(targetPos + offset, moveTime).onUpdate = () => + transform.LookAt(targetPos); + } + else + { + transform.position = targetPos + offset; + transform.LookAt(targetPos); + } + } } -} - - +} \ No newline at end of file