using System.Collections; using System.Collections.Generic; using System.Diagnostics.Eventing.Reader; using System.Linq; using UnityEngine; public class CameraSurround : MonoBehaviour { public static CameraSurround instance; /// /// 旋转点 /// private Vector3 m_RotationPoint; public Transform Pos; public Transform Distance_Pos; public float minDistance = 0.3f; // 摄像机最小距离目标点 public float zoomSpeed = 5f; // 缩放速度调整参数 private void Awake() { instance = this; } private void Update() { CameraCtrlRotate(); CameraCtrlMove(); CameraCtrlMouseScrllMove(); } /// /// 相机聚焦定位 /// /// public void SetCameraPosition(Transform target, bool reset = false, bool useMark = true, bool isSetTrans = false) { Bounds tmpBounds; if (useMark) { tmpBounds = GetBoundsByPartMark(target); } else { tmpBounds = GetBounds(target); } //物体最大长度 float a = tmpBounds.size.magnitude; if (tmpBounds.size != Vector3.zero) { if (reset) { if (tmpBounds.size.x > tmpBounds.size.z) { transform.position = tmpBounds.center + ((tmpBounds.center + new Vector3(0.2f, 0, 1)) - tmpBounds.center).normalized * a / 2 * 1.9f; } else { transform.position = tmpBounds.center + ((tmpBounds.center + new Vector3(1, 0.2f, 0)) - tmpBounds.center).normalized * a / 2 * 1.9f; } } else { transform.position = tmpBounds.center + (transform.position - tmpBounds.center).normalized * a / 2 * 1.9f; } } if (isSetTrans&& Pos!=null&&Distance_Pos!=null) { m_RotationPoint = Pos.position; /// transform.position = tmpBounds.center + (transform.position - tmpBounds.center).normalized * a / 5 * 1.9f; transform.position = Distance_Pos.position ; } else { m_RotationPoint = tmpBounds.center; } transform.LookAt(m_RotationPoint); } public void CameraCtrlMove() { float scroll = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroll) > 0.001f) { // 当前摄像机与旋转点距离 float currentDistance = Vector3.Distance(transform.position, m_RotationPoint); currentDistance = Mathf.Clamp(currentDistance, 0, 10); // 根据距离动态缩放速度(距离越小速度越慢) float dynamicSpeed = currentDistance * zoomSpeed * scroll; // 限制太近时不再向前推进 if (currentDistance < minDistance && scroll > 0) { return; } transform.position += transform.forward * dynamicSpeed; } } Vector3 PreMouseMPos; public void CameraCtrlMouseScrllMove() { if (Input.GetMouseButton(2)) { if (PreMouseMPos.x <= 0) { PreMouseMPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0.0f); } else { Vector3 CurMouseMPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0.0f); Vector3 offset = CurMouseMPos - PreMouseMPos; offset = -offset * 0.01f;//0.1这个数字的大小可以调节速度 transform.Translate(offset); PreMouseMPos = CurMouseMPos; } } else { PreMouseMPos = new Vector3(0.0f, 0.0f, 0.0f); } } private void CameraCtrlRotate() { var mouse_X = Input.GetAxis("Mouse X"); var mouse_Y = Input.GetAxis("Mouse Y"); if (Input.GetKey(KeyCode.Mouse1)) { if (m_RotationPoint.x.ToString() != "NaN" && m_RotationPoint.y.ToString() != "NaN" && m_RotationPoint.z.ToString() != "NaN") { transform.RotateAround(m_RotationPoint, Vector3.up, mouse_X * 5); transform.RotateAround(m_RotationPoint, transform.right, mouse_Y * -5); } else { SetCameraPosition(DeviceController.instance.transform, true); } } } /// /// 获取Transform及其子级的包围盒(MeshRenderer),若MeshRenderer包围盒长度为0,则获取BoxCollider包围盒 /// /// /// private static Bounds GetBoundsByPartMark(Transform target) { PartMark[] tmpPartMarks = target.GetComponentsInChildren(true); List tmpMeshRenders = new List(); foreach (var item in tmpPartMarks) { tmpMeshRenders.AddRange(item.GetMeshRender(item.transform)); } Bounds bounds = new Bounds(GetModelGroupBoundesConent(tmpMeshRenders.ToArray()), Vector3.zero); foreach (Renderer renderer in tmpMeshRenders) { bounds.Encapsulate(renderer.bounds); } return bounds; } private static Bounds GetBounds(Transform target) { MeshRenderer[] meshRenderers = target.GetComponentsInChildren().ToArray(); Bounds bounds = new Bounds(GetModelGroupBoundesConent(target.GetComponentsInChildren().ToArray()), Vector3.zero); foreach (Renderer renderer in meshRenderers) { bounds.Encapsulate(renderer.bounds); } return bounds; } /// /// 获取所以模型组的Boundes中心点 /// private static Vector3 GetModelGroupBoundesConent(Renderer[] renderers) { Vector3 conent = Vector3.zero; for (int i = 0; i < renderers.Length; i++) conent += renderers[i].bounds.center; //获取到中心点 conent /= renderers.Length; return conent; } }