using GCSeries.Core; using System; using Unity.Burst.CompilerServices; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using UnityEngine.UIElements; public class Show3DCamera : MonoBehaviour { public Vector3 targetPos; // 围绕旋转的目标点 public float rotateSpeed = 10f; // 旋转速度 public float moveSpeed = 10f; // 移动速度 public float distance = 10f; // 相机与目标的距离 public float distanceMin = 0.2f; public float distanceMax = 20f; public Vector2 pitchMinMax = new Vector2(-20, 80); // 相机俯仰角范围 private Vector3 offset; // 相机与目标的偏移量 private float yaw = 0f; // 偏航角(左右旋转) private float pitch = 0f; // 俯仰角(上下旋转) public static Show3DCamera instance; RectTransform inputRect; Camera self; private GameObject lastHitObject = null; private void Awake() { instance = this; self = transform.GetComponent(); DontDestroyOnLoad(this); gameObject.SetActive(false); } public void Set(Transform target, float rotateSpeed = 10, float moveSpeed = 0.1f, float distance = 0.1f, float pitchMin = -20, float pitchMax = 80, float distanceMin = 0.2f, float distanceMax = 20f, RectTransform inputRect = null) { if (target == null) { Debug.LogError("Target is not assigned!"); return; } 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); UpdateCameraPosition(); } void Update() { if (targetPos != null) { // 按住鼠标左键时旋转相机 if (Input.GetMouseButton(0)) { RotateCamera(); } // 鼠标滚轮缩放 float scroll = Input.GetAxis("Mouse ScrollWheel"); if (scroll != 0) { ZoomCamera(scroll); } // 按住鼠标右键时移动目标点 if (Input.GetMouseButton(1)) { MoveTarget(); } DetectHoveredObject(); } } // 检测鼠标悬停的物体 public void DetectHoveredObject() { GameObject obj = null; Vector2 mousePosition = Input.mousePosition; if (inputRect != null) { var pos = (mousePosition - (Vector2)inputRect.position) / inputRect.lossyScale - inputRect.rect.position; mousePosition = pos / inputRect.rect.size; } var ray = self.ViewportPointToRay(mousePosition); 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); lastHitObject = null; } } Debug.DrawLine(ray.origin, raycastHit.point, Color.red); } public void OnMouseEnterObj(GameObject obj) { TipItem tip = obj.GetComponent(); if (tip != null) { tip.OnEnter(); } } public void OnMouseExitObj(GameObject obj) { TipItem tip = obj.GetComponent(); if (tip != null) { tip.OnExit(); } } // 移动目标点 private void MoveTarget() { float mouseX = Input.GetAxis("Mouse X") * moveSpeed; float mouseY = Input.GetAxis("Mouse Y") * moveSpeed; transform.Translate(new Vector3(-mouseX, -mouseY, 0)); } // 缩放相机 private void ZoomCamera(float scroll) { distance -= scroll * 5f; // 调整缩放速度 distance = Mathf.Clamp(distance, distanceMin, distanceMax); // 限制距离范围 offset = new Vector3(0, 0, -distance); UpdateCameraPosition(); } // 旋转相机 private void RotateCamera() { // 获取鼠标移动量 float mouseX = Input.GetAxis("Mouse X") * rotateSpeed; float mouseY = Input.GetAxis("Mouse Y") * rotateSpeed; // 更新偏航角和俯仰角 yaw += mouseX; pitch -= mouseY; // 注意:鼠标 Y 轴移动方向与俯仰角相反 pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y); // 限制俯仰角范围 // 更新相机位置 UpdateCameraPosition(); } // 更新相机位置和朝向 private void UpdateCameraPosition() { // 计算旋转后的偏移量 Quaternion rotation = Quaternion.Euler(pitch, yaw, 0); Vector3 rotatedOffset = rotation * offset; // 更新相机位置 transform.position = targetPos + rotatedOffset; // 相机始终朝向目标点 transform.LookAt(targetPos); } }