using Cinemachine; using DG.Tweening; using HXSJFrameWork; using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using UnityEngine; public class CameraManager : MonoBehaviour { public static CameraManager _instance; public Camera mainCam;//主相机 public Camera singleCam;//单体化展示相机 public GameObject curentSingleObj;//当前单体化的模型 //第一人称巡查 public CinemachineDollyCart firstcart; public CinemachineSmoothPath firstPath; //第一人称巡查 public CinemachineDollyCart globalcart; public List globalpaths; //上帝视角巡查 public bool isInFirstRoam;//是否在第一人称漫游中 private float _roamSpeed = 1.5f;//巡查速度 private float camMoveSpeed = 10;//相机切换视角时的移动速度 private Vector3 camInitPos;//相机初始位置 private Vector3 camInitAngle;//相机初始角度 //待机时长 private float waitTime = 18; Tweener t_camAnimAngle;//相机转动动画 Tweener t_camAnimPos;//相机移动动画 private void Awake() { _instance = this; } // Start is called before the first frame update void Start() { camInitPos = mainCam.transform.position; camInitAngle = mainCam.transform.eulerAngles; } private float UnFocusTime = 0; //是否开始检测鼠标状态 private bool isStartCheck; //是否在漫游过程中 private bool isInRoam; // Update is called once per frame void Update() { //if (Input.GetKeyDown(KeyCode.O)) //{ // GlobalRoam(true); //} //if (Input.GetKeyDown(KeyCode.P)) //{ // GlobalRoam(false); //} //return; //处于第一人称漫游和不在第一个模块时,不计算待机时长 if (isInFirstRoam || MainUIManager._instance.curModuleIndex != 0) return; //鼠标有动静,清空计算无动静时长 if (Input.anyKey || Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0) { UnFocusTime = 0; isStartCheck = true; if (isInRoam) { Debug.Log("停止漫游"); isInRoam = false; GlobalRoam(false); } } if (isStartCheck) { //鼠标长时间未动,自动进入漫游 UnFocusTime += Time.deltaTime; if (UnFocusTime > waitTime) { UnFocusTime = 0; Debug.Log("长时间未动鼠标!"); isStartCheck = false; isInRoam = true; GlobalRoam(true); } } } /// /// 回到初始视角 /// public void InitView(Action call = null) { CameraMoveTarget(camInitPos, Quaternion.Euler(camInitAngle), () => { if (call != null) call(); }); } /// /// 第一人称漫游 /// /// true:开始巡查,false:结束巡查 public void FirstAutoRoam(bool isRoam) { if (isRoam) { isInFirstRoam = true; //从头开始 firstcart.m_Position = 0; firstcart.m_Speed = 0.01f; CameraStartRoam(firstcart.transform.position, Quaternion.Euler(firstcart.transform.eulerAngles), ()=>{ mainCam.GetComponent()._enabled = false; firstcart.m_Speed = _roamSpeed; mainCam.transform.parent = firstcart.transform; mainCam.transform.localPosition = Vector3.zero; mainCam.transform.localEulerAngles = Vector3.zero; }); } else { firstcart.m_Speed = 0; mainCam.transform.parent = transform; isInFirstRoam = false; //回到初始视角 CameraMoveTarget(camInitPos, Quaternion.Euler(camInitAngle)); } } //全局漫游协程 Coroutine i_globalroam; /// /// 长时间不动鼠标,全局俯视漫游 /// public void GlobalRoam(bool start) { if (start) { //开始全局漫游 i_globalroam = StartCoroutine(StartGlobalRoam()); } else { //停止全局漫游 StopCoroutine(i_globalroam); StopGlobalRoam(); } } /// /// 循环楼层 /// /// public IEnumerator StartGlobalRoam() { //(从零开始) int index = -1; while (true) { index++; index = index % MainUIManager._instance.buildFloorCount; //根据索引选择路径漫游 //globalcart.m_Path = globalpaths[index]; StartGlobalRoam(globalpaths[index]); //根据索引隐藏模型 MainUIManager._instance.ChangeFloor(index + 1); //第一次结束 Debug.Log("全局漫游索引"+index); Debug.Log(globalpaths[index].name +"长度"+ globalpaths[index].PathLength); Debug.Log("时间" + (globalpaths[index].PathLength / _roamSpeed)); yield return new WaitForSeconds(globalpaths[index].PathLength / _roamSpeed); } } /// /// 开始全局漫游(其中一层) /// /// 漫游路线 public void StartGlobalRoam(CinemachineSmoothPath path) { if (t_camAnimAngle != null) t_camAnimAngle.Kill(); if (t_camAnimPos != null) t_camAnimPos.Kill(); globalcart.m_Path = path; globalcart.m_Position = 0; globalcart.m_Speed = 0.01f; CameraStartRoam(globalcart.transform.position, Quaternion.Euler(globalcart.transform.eulerAngles.x + 75f, globalcart.transform.eulerAngles.y, globalcart.transform.eulerAngles.z), () => { mainCam.GetComponent()._enabled = false; globalcart.m_Speed = _roamSpeed; mainCam.transform.parent = globalcart.transform; mainCam.transform.localPosition = Vector3.zero; mainCam.transform.localEulerAngles = new Vector3(75f, 0, 0); }); } /// /// 停止全局漫游 /// private void StopGlobalRoam() { globalcart.m_Speed = 0; mainCam.transform.parent = transform; //恢复观察楼层 MainUIManager._instance.ChangeFloor(MainUIManager._instance.curfloor); //回到默认视角 InitView(); } /// /// 相机开始漫游,移动到漫游处,相机不可操作 /// /// /// /// public void CameraStartRoam(Vector3 endPos, Quaternion endAngle, Action call = null) { if (t_camAnimAngle != null) t_camAnimAngle.Kill(); if (t_camAnimPos != null) t_camAnimPos.Kill(); mainCam.GetComponent()._enabled = false; float dis = float.Parse((mainCam.transform.position - endPos).magnitude.ToString("f3")); //Debug.Log(dis+"@@@@@@"); float time = dis / camMoveSpeed; t_camAnimPos = mainCam.transform.DOMove(endPos, time); t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() => { if (call != null) call(); }); } /// /// 相机直接移到目标位置(点击设备、人物等移动视角) /// /// 相机终点位置 /// 相机终点角度 public void CameraMoveTarget(Vector3 endPos, Quaternion endAngle, Action call = null) { if (t_camAnimAngle != null) t_camAnimAngle.Kill(); if (t_camAnimPos != null) t_camAnimPos.Kill(); mainCam.GetComponent()._enabled = false; float dis = float.Parse((mainCam.transform.position - endPos).magnitude.ToString("f3")); //Debug.Log(dis+"@@@@@@"); float time = dis / camMoveSpeed; t_camAnimPos = mainCam.transform.DOMove(endPos, time); t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() => { if (call != null) call(); CameraEnable(); }); } /// /// 移动相机:先拉高,再移动到目标视角 /// /// /// public void CamerMoveAnimAfter(Vector3 endPos, Quaternion endAngle, Action call = null) { if (t_camAnimAngle != null) t_camAnimAngle.Kill(); if (t_camAnimPos != null) t_camAnimPos.Kill(); mainCam.GetComponent()._enabled = false; float dis = (mainCam.transform.position - camInitPos).magnitude; float time = dis / camMoveSpeed; Vector3 hightpoint = new Vector3(mainCam.transform.position.x, ModelManager.instance.wudingHeight+10f, mainCam.transform.position.z); t_camAnimPos = mainCam.transform.DOMove(hightpoint, time); t_camAnimAngle = mainCam.transform.DORotate(camInitAngle, time).OnComplete(() => { t_camAnimPos.Kill(); t_camAnimAngle.Kill(); t_camAnimPos = mainCam.transform.DOMove(endPos, time); t_camAnimAngle = mainCam.transform.DORotate(endAngle.eulerAngles, time).OnComplete(() => { if (call != null) call(); CameraEnable(); }); }); } /// /// 开启相机可操作性 /// private void CameraEnable() { mainCam.GetComponent().InitTarget(); mainCam.GetComponent()._enabled = true; } /// /// 移动相机:相机在房间内,先回到初始角度再移至目标位置,相机在房间外,直接移动到目标位置 /// /// /// public void CameraMoveAnim(Vector3 endPos, Quaternion endAngle, Action call = null) { bool inview = true; //判断物体是否在相机视角内TODO:前方是否有物体遮挡 Vector3 viewPos = mainCam.WorldToViewportPoint(endPos); // z<0代表在相机背后 if (viewPos.z < 0) inview = false; //太远了!看不到了! if (viewPos.z > mainCam.farClipPlane) inview = false; // x,y取值在 0~1之外时代表在视角范围外; if (viewPos.x < 0 || viewPos.y < 0 || viewPos.x > 1 || viewPos.y > 1) inview = false; if (inview) { CameraMoveTarget(endPos, endAngle, call); } else { CamerMoveAnimAfter(endPos, endAngle, call); } } /// /// 视角居中 /// /// 当前居中的点位 /// 当前居中的点位 /// 当前居中的点位 public void ViewCenterPoint(GameObject curPoint, Vector3 forward, float dis = 3, Action call = null) { Debug.Log("web:" + curPoint.name); //获取模型中心点位置(加上模型方向*3) Vector3 playerPos = curPoint.transform.position + forward * dis; Quaternion angle = Quaternion.LookRotation(-forward); ; Debug.Log("pos" + playerPos + ";angle" + angle); CameraMoveAnim(playerPos, angle, call); } }