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;
}
}