using UnityEngine; using UnityEngine.EventSystems; public class ControlMove : MonoBehaviour { private float moveSpeed = 50f; // 右键平移速度 [Header("滚轮缩放速度系数")] public float zoomSpeed = 10f; // 滚轮缩放速度 [Header("相机与水库中心的最大距离")] public float maxDistance = 600f; // 最大缩放距离 [Header("相机的最大高度限制")] public float maxHeight = 220f; // 最大高度限制 [Header("右键平移速度衰减系数")] public float rightClickPanSpeed = 100f; // 右键平移速度除数 private Vector3 inScript; // 引用焦点脚本,提供 core [Header("左键拖拽旋转灵敏度系数")] public float rotationSensitivity = 0.2f; // 左键拖拽旋转灵敏度 private Camera cam; // 主相机引用 private bool isRotating = false; // 是否正在旋转标志 private Vector2 lastMousePos; // 上次鼠标位置(用于旋转计算) [Header("初始距离中心")] public Vector3 reservoirCenter; // 水库中心坐标 [Header("初始旋转中心")] public Vector3 startinScript; // 初始焦点位置 private Rigidbody rb; // 刚体组件(如需要物理模拟) private bool isCameraCtrl = true; // 相机是否可控制 //相机操作有效性判断 private bool isClickUI = false; void Start() { rb = GetComponent(); cam = Camera.main; if (inScript == Vector3.zero) { GetInScriptCore(); } } void Update() { if (isCameraCtrl) { //操作有效性判断 if (EventSystem.current != null) { if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2)) { isClickUI = EventSystem.current.IsPointerOverGameObject(); } if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1) || Input.GetMouseButtonUp(2)) { isClickUI = false; } } if (!isClickUI) { Vector3 core = inScript; // —— 右键平移 —— if (Input.GetMouseButton(1)) { moveSpeed = Vector3.Distance(core, transform.position) / 2f; float mx = Input.GetAxis("Mouse X"); float my = Input.GetAxis("Mouse Y"); // Vector3 desiredPosition = transform.position + (-transform.right * mx + -transform.up * my) * moveSpeed * Time.deltaTime; Vector3 desiredPosition = transform.position + (-transform.right * mx + -transform.up * my) * moveSpeed / rightClickPanSpeed; // 判断是否与障碍物发生碰撞 if (!WillCollideWithObstacle(desiredPosition)) { // transform.position = Vector3.Lerp(transform.position, desiredPosition, moveSpeed * Time.deltaTime); transform.position = desiredPosition; } } // —— 滚轮缩放 —— float scroll = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroll) > 0.001f) { Vector3 desiredPosition = transform.position + transform.forward * scroll * zoomSpeed; // 判断是否与障碍物发生碰撞 if (!WillCollideWithObstacle(desiredPosition)) { transform.position = desiredPosition; } } // —— 左键开始/结束旋转 —— if (Input.GetMouseButtonDown(0)) { isRotating = true; lastMousePos = Input.mousePosition; } if (Input.GetMouseButtonUp(0)) { isRotating = false; } // —— 左键拖拽:RotateAround 实现 + 俯仰限制 —— if (isRotating && Input.GetMouseButton(0)) { Vector2 curr = Input.mousePosition; Vector2 delta = (curr - lastMousePos) * rotationSensitivity; lastMousePos = curr; /* */ // 1. 水平绕世界 Y 轴旋转 //Vector3 desiredPosition = transform.position; //transform.RotateAround(core, Vector3.up, delta.x); Vector3 localPosHorizonal = transform.position - core; Quaternion rotationHorizonal = Quaternion.AngleAxis(delta.x, Vector3.up); Vector3 newLocalPosHorizonal = rotationHorizonal * localPosHorizonal; Vector3 newPosHorizonal = core + newLocalPosHorizonal; // 检查旋转后是否发生碰撞 if (!WillCollideWithObstacle(newPosHorizonal)) { // 如果没有碰撞,执行旋转 transform.RotateAround(core, Vector3.up, delta.x); } else { // 如果碰撞了,撤销旋转,恢复到原来的位置 } // 2. 俯仰旋转 Vector3 dir = (transform.position - core).normalized; Vector3 flat = new Vector3(dir.x, 0f, dir.z).normalized; float selfFlatX = transform.forward.x; float selfFlatZ = transform.forward.z; Vector3 selfFlat = new Vector3(selfFlatX, 0f, selfFlatZ).normalized; float selfPitch = Vector3.SignedAngle(selfFlat, transform.forward, transform.right); if (selfPitch <= 80f && selfPitch >= 0f) { float pitchDelta = delta.y * -1f; Vector3 localPosVertical = transform.position - core; Quaternion rotationVertical = Quaternion.AngleAxis(pitchDelta, transform.right); Vector3 newPosVertical = core + rotationVertical * localPosVertical; if (!WillCollideWithObstacle(newPosVertical)) { transform.RotateAround(core, transform.right, pitchDelta); } } else if (selfPitch > 80f) { float pitchDelta = delta.y * -1f; if (pitchDelta < 0f) { transform.RotateAround(core, transform.right, pitchDelta); } } else if (selfPitch < 0f) { float pitchDelta = delta.y * -1f; if (pitchDelta > 0f) { transform.RotateAround(core, transform.right, pitchDelta); } } } } } } // 碰撞检测方法 bool WillCollideWithObstacle(Vector3 targetPosition) { // 计算从当前位置到目标位置的方向和距离 Vector3 moveDir = targetPosition - transform.position; float moveDist = moveDir.magnitude; // 使用 SphereCast 检查即将到达的位置是否会与障碍物发生碰撞 RaycastHit hit; if (Physics.SphereCast(transform.position, 0.5f, moveDir.normalized, out hit, moveDist, LayerMask.GetMask("Default"), QueryTriggerInteraction.Collide)) { // 如果检测到碰撞,返回 true // Debug.Log("collider"); return true; } else if (Vector3.Distance(targetPosition, reservoirCenter) < maxDistance && targetPosition.y < maxHeight) { // 如果在范围内,返回 false return false; } else // Debug.Log("outRange"); return true; } public void GetInScriptCore() { inScript = startinScript; } public void GetInScriptCore(Vector3 position) { inScript = position; } public void StartCameraControl() { isCameraCtrl = true; isClickUI = false; } //停止相机控制 public void StopCameraControl() { isCameraCtrl = false; } }